/// <summary> /// 인지범위안에 다른 트리거나 플레이어가 들어왔다면 호출됩니다. /// </summary> /// <param name="target"></param> void OnSetTarget(GameObject target) { TargetPlayer = target; TargetTransform = TargetPlayer.transform; //타겟을 향해 이동하는 상태로 전환 goblinState = GoblinState.MoveToTarget; }
void CheckDamage() { if (damaged == true) { currentState = GoblinState.damaged; } }
void CheckHealth() { if (hp <= 0) { currentState = GoblinState.death; } }
public void ApplyDamage(float damage) { currentHealth -= damage; if (currentHealth <= 0) { currentState = GoblinState.dead; } }
private void Frozen() { if (frozenCountdown <= 0) currentState = previousState; else { frozenCountdown -= Time.deltaTime; } }
IEnumerator AiDmgManager() { thisAnimator.SetBool("damage", true); yield return(new WaitForSeconds(2f)); thisAnimator.SetBool("damage", false); currentState = GoblinState.idle; damaged = false; }
IEnumerator AiDelayManager() { thisAnimator.SetBool("moving", false); thisAnimator.SetBool("attacking", false); yield return(new WaitForSeconds(2f)); currentState = GoblinState.idle; attacking = false; }
// All State managers ================================================================================================================================= IEnumerator AiAtkManager() { attacking = true; thisAnimator.SetBool("attacking", true); yield return(new WaitForSeconds(1f)); thisAnimator.SetBool("attacking", false); currentState = GoblinState.delay; }
/// <summary> /// 대기하는 동작. /// </summary> /// <returns></returns> IEnumerator WaitUpdate() { goblinState = GoblinState.Wait; float waitTime = Random.Range(1.0f, 3.0f); yield return(new WaitForSeconds(waitTime)); goblinState = GoblinState.Idle; }
/// <summary> /// 공격 상태 /// </summary> void AttackUpdate() { float distance = Vector3.Distance(targetTransform.position, myTransform.position); if (distance > attackRange + 0.5f) { // 타겟과의 거리가 멀어졌다면 타겟으로 이동 goblinState = GoblinState.MoveToTarget; } }
/// <summary> /// 공격 상태일때의 동작 /// </summary> void AttackUpdate() { //이걸 사용하면 무겁다. 해서 diff 를 사용해서 하는데 공부용으로 쓴다. float distance = Vector3.Distance(TargetTransform.position, myTransform.position); if (distance > AttackRange + 0.5f) { //타켓과의 거리가 걸어지면 타겟으로 이동합니다. goblinState = GoblinState.MoveToTarget; } }
private void Frozen() { if (frozenCountdown <= 0) { currentState = previousState; } else { frozenCountdown -= Time.deltaTime; } }
public override object GetState() { GoblinState s = new GoblinState { Position = transform.position, Rotation = transform.rotation, Health = this.Health, CanMove = _canMove }; return(s); }
public void SetState(GoblinState newState) { if (_isinit) { _states[_currentState].enabled = false; _states[_currentState].EndState(); } _currentState = newState; _states[_currentState].BeginState(); _states[_currentState].enabled = true; _anim.SetInteger("CurrentState", (int)_currentState); }
void OnCollisionEnter2D(Collision2D col) { if (col.gameObject.name == "Tower") { StartCoroutine(HitTower()); GameObject.Find("GameManager").GetComponent <GameManager>().towerLost = true; currentState = GoblinState.idle; } else if (col.gameObject.tag == "AttackProjectile") { currentState = GoblinState.dead; } }
/// <summary> /// 이동 상태에서 동작 /// </summary> void MoveUpdate() { Vector3 diff = Vector3.zero; Vector3 lookAtPosition = Vector3.zero; switch (goblinState) { case GoblinState.Patrol: if (targetPosition != Vector3.zero) { diff = targetPosition - myTransform.position; // 목표지점까지 거의 왔으면 if (diff.magnitude < attackRange) { StartCoroutine(WaitUpdate()); return; } lookAtPosition = new Vector3(targetPosition.x, myTransform.position.y, targetPosition.z); } break; case GoblinState.MoveToTarget: if (targetPosition != null) { diff = targetPlayer.transform.position - myTransform.position; // 타겟과 충분히 가까워졌다면 if (diff.magnitude < attackRange) { goblinState = GoblinState.Attack; return; } lookAtPosition = new Vector3(targetPlayer.transform.position.x, myTransform.position.y, targetPlayer.transform.position.z); } break; } Vector3 direction = diff.normalized; direction = new Vector3(direction.x, 0.0f, direction.z); Vector3 moveAmount = direction * moveSpeed * Time.deltaTime; myTransform.Translate(moveAmount, Space.World); myTransform.LookAt(lookAtPosition); }
//이동 상태에서의 동작. Patrol, MoveToTarget void MoveUpdate() { //두 벡터의 차 Vector3 diff = Vector3.zero; Vector3 lookAtPosition = Vector3.zero; switch (goblinState) { case GoblinState.Patrol: if (TargetPosition != Vector3.zero) { diff = TargetPosition - myTransform.position; //목표지점까지 거의 왔으면. if (diff.magnitude < AttackRange) { StartCoroutine(WaitUpdate()); return; } lookAtPosition = new Vector3(TargetPosition.x, myTransform.position.y, TargetPosition.z); } break; case GoblinState.MoveToTarget: if (TargetPosition != null) { diff = TargetPlayer.transform.position - myTransform.position; if (diff.magnitude < AttackRange) { goblinState = GoblinState.Attack; return; } lookAtPosition = new Vector3(TargetPlayer.transform.position.x, myTransform.position.y, TargetPlayer.transform.position.z); } break; } Vector3 direction = diff.normalized; //방향만 얻는다. direction = new Vector3(direction.x, 0.0f, direction.z); Vector3 moveAmount = direction * MoveSpeed * Time.deltaTime; //이동 myTransform.Translate(moveAmount, Space.World);//관련된 축을 월드축방향으로 이동시킨다. //바라보게 하기 myTransform.LookAt(lookAtPosition); }
/// <summary> /// 충돌 검출 /// </summary> /// <param name="other"></param> private void OnTriggerEnter(Collider other) { if (other.gameObject.CompareTag("PlayerAttack") == true) { hp -= 10; if (hp > 0) { Instantiate(damageEffect, other.transform.position, Quaternion.identity); anim.CrossFade(damageAnimClip.name); DamageTweenEffect(); } else { goblinState = GoblinState.Die; } } }
public override void SetState(object state) { if (state is GoblinState) { GoblinState s = (GoblinState)state; transform.position = s.Position; transform.rotation = s.Rotation; Health = s.Health; _canMove = s.CanMove; } else { Debug.LogError("Unable to restore object state! Something went deeply wrong.. " + gameObject.name); } }
/// <summary> /// 피격되었는지 확인 하는 함수 /// </summary> /// <param name="other"></param> private void OnTriggerEnter(Collider other) { //플레이어의 공격에 맞았다면 if (other.gameObject.CompareTag("PlayerAttack")) { HP -= 10; if (HP > 0) { //피격 이펙트 생성. Instantiate(DamageEffact, other.transform.position, Quaternion.identity); myAnimation.CrossFade(DamageAnimClip.name); } else { goblinState = GoblinState.Die; } //myAnimation.CrossFade() } }
// Use this for initialization void Start() { goblinState = GoblinState.Idle; // 캐싱 anim = GetComponent <Animation>(); myTransform = GetComponent <Transform>(); // 애니메이션 클립들 기본 세팅 anim[idleAnimClip.name].wrapMode = WrapMode.Loop; anim[moveAnimClip.name].wrapMode = WrapMode.Loop; anim[attackAnimClip.name].wrapMode = WrapMode.Once; anim[damageAnimClip.name].wrapMode = WrapMode.Once; anim[damageAnimClip.name].layer = 10; anim[dieAnimClip.name].wrapMode = WrapMode.Once; anim[dieAnimClip.name].layer = 10; // 애니메이션 이벤트 추가 AddAnimationEvent(attackAnimClip, "OnAttackAnimFinished"); AddAnimationEvent(damageAnimClip, "OnDamageAnimFinished"); AddAnimationEvent(dieAnimClip, "OnDieAnimFinished"); skinnedMeshRenderer = myTransform.Find("body").GetComponent <SkinnedMeshRenderer>(); }
void Start() { goblinState = GoblinState.Idle; //캐싱 myAnimation = GetComponent <Animation>(); myTransform = GetComponent <Transform>(); //애니메이션 클립들 기본 세팅 myAnimation[IdleAnimClip.name].wrapMode = WrapMode.Loop; myAnimation[MoveAnimClip.name].wrapMode = WrapMode.Loop; myAnimation[AttackAnimClip.name].wrapMode = WrapMode.Once; myAnimation[DamageAnimClip.name].wrapMode = WrapMode.Once; myAnimation[DamageAnimClip.name].layer = 10; myAnimation[DieAnimClip.name].wrapMode = WrapMode.Once; myAnimation[DamageAnimClip.name].layer = 10; //애니메이션 이벤트 추가 AddAnimationEvent(AttackAnimClip, "OnAttackAnimFinished"); AddAnimationEvent(DamageAnimClip, "OnDamageAnimFinished"); AddAnimationEvent(DieAnimClip, "OnDieAnimFinished"); //스킨 메쉬를 캐싱. skinMeshRenderer = myTransform.Find("body").GetComponent <SkinnedMeshRenderer>(); }
public void ChangeState(GoblinState newState) { state = newState; switch (state) { case GoblinState.Idle: m_Rigidbody.drag = 5; m_Rigidbody.angularDrag = 10; m_Animator.SetBool("Sitting", isSitting); break; case GoblinState.RunAway: case GoblinState.Chase: isSitting = false; m_Animator.SetBool("Sitting", isSitting); m_Rigidbody.drag = 5; m_Rigidbody.angularDrag = 10; break; case GoblinState.Dead: isSitting = false; m_Animator.SetBool("Sitting", isSitting); foreach (Goblin sub in subscribedGOs) { sub.OnDeath -= FriendDied; } if (OnDeath != null) { OnDeath(); } GameManager.instance.AddScore(scoreValue); feetCollider.enabled = false; m_Rigidbody.drag = 0; m_Rigidbody.angularDrag = 0.5f; break; } }
/// <summary> /// 대기 상태일때 동작 /// </summary> void IdleUpdate() { // 만약 타겟 플레이어가 없다면, 임의의 지점을 랜덤하게 선택해서 레이캐스트를 이용하여 // 임의의 지점의 높이값까지 구해서 그 임의의 지점으로 이동시켜주도록 한다 if (targetPlayer == null) { targetPosition = new Vector3(myTransform.position.x + Random.Range(-10.0f, 10.0f), myTransform.position.y + 1000.0f, myTransform.position.z + Random.Range(-10.0f, 10.0f)); Ray ray = new Ray(targetPosition, Vector3.down); RaycastHit hit = new RaycastHit(); if (Physics.Raycast(ray, out hit, Mathf.Infinity) == true) { // 임의의 위치 높이값 targetPosition.y = hit.point.y; } goblinState = GoblinState.Patrol; } else { goblinState = GoblinState.MoveToTarget; } }
// All checks ========================================================================================================================================== void CheckDistance() { if ((Vector3.Distance(target.position, transform.position) <= attackRadius) && (currentState != GoblinState.attack)) { currentState = GoblinState.attack; setChase = false; } if (Vector3.Distance(target.position, transform.position) <= chaseRadius && Vector3.Distance(target.position, transform.position) >= attackRadius) { currentState = GoblinState.chase; setChase = true; } if (Vector3.Distance(target.position, transform.position) >= chaseRadius && Vector3.Distance(target.position, transform.position) >= attackRadius) { currentState = GoblinState.idle; setChase = false; } }
/// <summary> /// 대기 상태일때의 동작 /// </summary> void IdleUpdate() { //만약 타겟 플레이어가 없다면, 임의의 지점을 랜덤하게 선택해서 레이캐스트를 이용하여 //임의의 지점의 높이값까지 구해서 그 임의의 지점으로 이동시켜주도록 합니다. if (TargetPlayer == null) { TargetPosition = new Vector3(myTransform.position.x + Random.Range(-10.0f, 10.0f), myTransform.position.y + 1000.0f//y값이 엄청 높은 상태 , myTransform.position.z + Random.Range(-10.0f, 10.0f)); Ray ray = new Ray(TargetPosition, Vector3.down); RaycastHit raycastHit = new RaycastHit(); if (Physics.Raycast(ray, out raycastHit, Mathf.Infinity)) { //임의의 위치의 높이값 TargetPosition.y = raycastHit.point.y; } //상태를 정찰 상태로 변경. goblinState = GoblinState.Patrol; } else { //타겟이 있다면 타겟을 향해 이동합니다. goblinState = GoblinState.MoveToTarget; } }
public void StartWalkingLeft(float speedMultiplier) { //Debug.Log("Speed multiplier: " + speedMultiplier + "\nSpeed: " + baseSpeed + "\nNew Speed: " + (baseSpeed * speedMultiplier)); currentState = GoblinState.walking; speed = baseSpeed * speedMultiplier; }
public void Freeze(float durationInSeconds) { frozenCountdown = durationInSeconds; previousState = currentState; currentState = GoblinState.frozen; }
/// <summary> /// 인지범위 안에 다른 트리거나 플레이어가 들어왔다면 호출 /// </summary> /// <param name="target"></param> void OnSetTarget(GameObject target) { targetPlayer = target; targetTransform = targetPlayer.transform; goblinState = GoblinState.MoveToTarget; }
void OnCollisionEnter2D(Collision2D col) { if (col.gameObject.name == "Tower") { StartCoroutine(HitTower()); GameObject.Find("GameManager").GetComponent<GameManager>().towerLost = true; currentState = GoblinState.idle; } else if (col.gameObject.tag == "AttackProjectile") { currentState = GoblinState.dead; } }