Unity/Asset 분석

[RTS Engine] Attack, AttackObjectLauncher 구조

lipnus 2022. 1. 5. 19:49
반응형

AttackEntity.cs

public abstract class AttackEntity : MonoBehaviour, IEntityComponent {
	// ...
    
	//handles launching attack objects in case of an indirect attack.
	[SerializeField] private AttackObjectLauncher attackObjectLauncher = new AttackObjectLauncher();

 

 

AttackObjectLauncher.cs

[System.Serializable]
public class AttackObjectLauncher
{
  AttackEntity source;

  public enum LaunchTypes { random, inOrder};
  //random: one attack source from the below array will be randomly chosen and triggered
  //in Order: the attack will trigger all elements of the below array in their order.
  [SerializeField]
  private LaunchTypes launchType = LaunchTypes.inOrder;

  [System.Serializable]
  public class Source
  {
  [SerializeField]
  private EffectObj attackObject = null; //the attack object that will be launched from this source.
  [SerializeField]
  private Transform launchPosition = null; //this is where the attack object will be launched from.
  [SerializeField, Tooltip("The initial rotation that the attack object will have as soon as it is spawned.")]
  private Vector3 launchRotationAngles = Vector3.zero;
  
  // ...

 

AttackObject.cs (실제로 날아가는 애들)

    void OnTriggerEnter(Collider other)
    {
        //delay timer is still going and we can't damage in delay time + make sure that no damage has been applied or damaging multiple times is enabled
        if (isActive == false || effectObjComp.CurrentState != EffectObj.State.running || delayTimer > 0.0f && damageInDelay == false && (didDamage == false || damageOnce == false))
            return;

        if(RTSHelper.IsInLayerMask(obstacleLayerMask, other.gameObject.layer)) //Check if this is an obstacle that stops the attack object.
        {
            ApplyDamage(other.gameObject, null, transform.position);
            return;
        }

        SelectionEntity hitSelection = other.gameObject.GetComponent<SelectionEntity>();
        //if the attack object didn't enter in collision with a selection entity or it did but it was one belonging to resource
        if (hitSelection == null || hitSelection.FactionEntity == null)
            return;

        //make sure the faction entity belongs to an enemy faction and that it's not dead yet:
        if ((hitSelection.FactionEntity.FactionID != sourceFactionID || damageFriendly) && hitSelection.FactionEntity.EntityHealthComp.IsDead() == false)
            ApplyDamage(other.gameObject, hitSelection.FactionEntity, hitSelection.transform.position);
    }

    //a method called to apply damage to a target (position)
    private void ApplyDamage (GameObject targetObject, FactionEntity target, Vector3 targetPosition)
    {
        damage.TriggerAttack(target, targetPosition, sourceFactionID, true); //deal damage
        didDamage = true;

        //show damage effect:
        gameMgr.EffectPool.SpawnEffectObj(hitEffect, transform.position, Quaternion.identity, targetObject.transform); //Get the spawn effect obj
        gameMgr.AudioMgr.PlaySFX(target ? target.AudioSourceComp : targetObject.GetComponent<AudioSource>(), hitAudio, false);

        if (target && childOnDamage == true) //if the attack object is supposed to become a child object of its target on damage:
            transform.SetParent(target.transform, true);

        if (destroyOnDamage == true) //if this object gets hidden on damage
        {
            effectObjComp.Disable(); //disable from the effect object component
            isActive = false; //set as inactive
        }
    }

 

 

 

데미지 판정의 기준은 AttackObject와 Unit의 Collider 충돌

 

AttackObject(발사체)의 Init(), Enable() Method가 호출되어서

damage, Effect, gameMgr 등이 세팅된 상태에서 적에게 처박으면 OnTriggerEnger() 호출되면서 데미지 판정여부를 결정함.

 

 

-> 이걸 그대로 쓰던지, 유사하게 새로 만들어서 범위공격 Skill 구현

 

 

반응형