c# 강의/유니티

20200507 - 애니메이션2

쪼혀 2020. 5. 8. 07:55

 

> 타격 프레임 code

더보기
public GameObject model;
public Button btn;
public int attackFrame;

private Animation anim;
private AnimationState state;

public int attackFrame;
private float totalFrames;
private float attackTime;
private float elapsedTimeAttack;  //타격 시간 
private float elapsedTimeAttackComplete;  //공격 애니메이션 종료 시간 
private bool isAttackAnimationPlaying;  //공격애니메이션 실행중인지 
private bool isAttack;  //공격을 했는지 

void Start()
{
    this.anim = this.model.GetComponent<Animation>();
    this.state = this.anim["attack_sword_01"];
    this.totalFrames = state.length * state.clip.frameRate;
    // fps의 뜻 (60fps, 30fps, 29.97fps, 24fps) 
    // 영상에서 매 초당 보여지는 이미지 장면의 수, 즉 프레임이 재생되는 속도

    // 22 : 8 = 0.733 : x 
    // 8 * 0.733 / 22 = x 
    this.attackTime =
        this.attackFrame * state.length / this.totalFrames;

}

void Update()
{
    //공격 애니메이션 실행 중이라면 
    if (this.isAttackAnimationPlaying)
    {
        //경과시간 누적 
        this.elapsedTimeAttack += Time.deltaTime;
        if (this.elapsedTimeAttack >= this.attackTime)
        {
            if (!this.isAttack)
            {
                //공격을 했는지 
                Debug.Log("타격!");
                this.isAttack = true;
            }
        }

        this.elapsedTimeAttackComplete += Time.deltaTime;

        if (this.elapsedTimeAttackComplete >= this.state.length)
        {
            //공격 애니메이션 종료 
            this.elapsedTimeAttack = 0;
            this.elapsedTimeAttackComplete = 0;
            this.isAttack = false;
            this.isAttackAnimationPlaying = false;
            this.anim.Play("idle@loop");
            Debug.Log("공격 애니메이션 종료");
        }
    }
}

 

> 이동

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.UI;
 
public class App : MonoBehaviour
{
    public Animation anim;
    public Button btnMoveForward;
    public Button btnMoveBack;
    public Button btnMoveLeft;
    public Button btnMoveRight;
    public Button btnStop;
    public float speed;
 
    private bool isMove;
    private Vector3 dir;
 
 
    void Start()
    {
        this.btnMoveForward.onClick.AddListener(() => {
            this.Move(Vector3.forward);
        });
 
        this.btnMoveBack.onClick.AddListener(() => {
            this.Move(Vector3.back);
        });
 
        this.btnMoveRight.onClick.AddListener(() => {
            this.Move(Vector3.right);
        });
 
        this.btnMoveLeft.onClick.AddListener(() => {
            this.Move(Vector3.left);
        });
 
 
        this.btnStop.onClick.AddListener(() => {
            Debug.Log("Stop");
            this.Stop();
        });
    }
 
    private void Move(Vector3 dir) {
        this.dir = dir;
        this.anim.Play("run@loop");
        this.isMove = true;
    }
 
    private void Stop() {
        this.isMove = false;
        this.anim.Play("idle@loop");
    }
 
    private void Update()
    {
        if (this.isMove) {
            this.anim.gameObject.transform.Translate(this.dir * this.speed * Time.deltaTime);
        }
    }
}

* 방향, 속도, 시간

 

> 오브젝트와의 거리 계산

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.UI;
 
public class App : MonoBehaviour
{
    public GameObject model;
    public GameObject target;
    public Button btnMove;
 
    private bool isMove;
    private Animation anim;
 
    void Start()
    {
        this.anim = this.model.GetComponent<Animation>();
 
        this.btnMove.onClick.AddListener(() => {
            this.Move();
        });
    }
 
    private void Move() {
        this.isMove = true;
        this.anim.Play("run@loop");
    }
 
    private void Stop() {
        this.isMove = false;
        this.anim.Play("idle@loop");
    }
 
    private void Update()
    {
        if (this.isMove) {
            //float
            var distance = Vector3.Distance(model.transform.position,
                target.transform.position);
 
            //move
            var speed = 1.2f;
            var dir = Vector3.forward;
            this.model.transform.Translate(speed * dir * Time.deltaTime);
 
            Debug.Log(distance);
 
            if (distance <= 0.03f)
            {
                this.model.transform.position = this.target.transform.position;
                this.Stop();
            }
        }
 
    }
}

 

> 히트&다이(프레임계산 적용)

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.UI;
 
public class App : MonoBehaviour
{
    public GameObject model;
    public GameObject target;
    public Button btnMove;
    public float attackDely;
 
    private bool isMove;
    private bool isAttack;
    private Animation heroAnim;
    private Animation monsterAnim;
    private float elapsedTime;
    private int attackFrame;
    private float totalFrames;
    private float attackTime;
    private int attackCount;    //공격 몇번 했는지 카운트 
    private bool isImpact;   //타격 했나?
    private AnimationState attackAnimState;
    private bool isMonsterHit;
    private float monsterHitElapsedTime;
    private float monsterAttackDamageAnimLength;
    private float attackDelayElapsedTime;
    private bool isContinousAttack;
    private bool isMonsterDie;
    private float monsterDieElapsedTime;
    private float monsterDieAnimationLength;
 
 
    void Start()
    {
        //init
        this.attackFrame = 8;
        this.heroAnim = this.model.GetComponent<Animation>();
        this.monsterAnim = this.target.GetComponent<Animation>();
        this.monsterAttackDamageAnimLength = this.monsterAnim["Anim_Damage"].length;
        this.monsterDieAnimationLength = this.monsterAnim["Anim_Death"].length;
 
        this.attackAnimState = this.heroAnim["attack_sword_01"];
        this.totalFrames = this.attackAnimState.length * this.attackAnimState.clip.frameRate;
        //22 : 8 = 0.733 : x 
        // x = 8 * 0.733 / 22
        this.attackTime = this.attackFrame * this.attackAnimState.length / this.totalFrames;
 
        this.btnMove.onClick.AddListener(() => {
            this.Move();
        });
    }
 
    private void Move() {
        this.isMove = true;
        this.heroAnim.Play("run@loop");
    }
 
    private void Stop() {
        this.isMove = false;
        this.Idle();
    }
 
    private void Idle() {
        this.heroAnim.Play("idle@loop");
    }
 
    private void Attack() {
        this.isAttack = true;
        this.heroAnim.Play("attack_sword_01");
    }
 
    private void MonsterHit() {
        this.isMonsterHit = true;
        this.monsterAnim.Play("Anim_Damage");
    }
 
    private void MonsterIdle() {
        this.isMonsterHit = false;
        this.monsterAnim.Play("Anim_Idle");
    }
 
    private void Update()
    {
        if (this.isMove) {
            //float
            var distance = Vector3.Distance(model.transform.position,
                target.transform.position);
 
            //move
            var speed = 1.2f;
            var dir = Vector3.forward;
            this.model.transform.Translate(speed * dir * Time.deltaTime);
 
            if (distance <= 0.5f)
            {
                this.Stop();
                this.Attack();
            }
        }
 
        if (this.isAttack) {
 
            this.elapsedTime += Time.deltaTime;
            if (this.elapsedTime >= attackTime)
            {
                if (this.isImpact == false) {
                    isImpact = true;
                    this.MonsterHit();
                }
            }
 
            if (this.elapsedTime >= this.attackAnimState.length) {
                //공격 완료 
                this.isAttack = false;
                this.isImpact = false;
                this.elapsedTime = 0;
                this.attackCount++;
 
                Debug.Log(this.attackCount);
                
                this.Idle();
 
                if (this.attackCount >= 3) {
                    this.isContinousAttack = false;
                    this.MonsterDie();
                }
 
                
            }
        }
 
 
        if (this.isMonsterHit) {
            this.monsterHitElapsedTime += Time.deltaTime;
            if (this.monsterHitElapsedTime >= monsterAttackDamageAnimLength)
            {
                this.monsterHitElapsedTime = 0;
                this.MonsterIdle();
                this.isContinousAttack = true;
            }
        }
 
        if (this.isContinousAttack) {
            this.attackDelayElapsedTime += Time.deltaTime;
            if (this.attackDelayElapsedTime >= this.attackDely) {
                this.attackDelayElapsedTime = 0;
                this.isContinousAttack = false;
                this.Attack();
            }
        }
 
        if (this.isMonsterDie) {
            this.monsterDieElapsedTime += Time.deltaTime;
            if (this.monsterDieElapsedTime >= this.monsterDieAnimationLength) {
                UnityEngine.Object.Destroy(this.target.gameObject);
            }
        }
 
    }
 
    private void MonsterDie()
    {
        this.monsterAnim.Play("Anim_Death");
        this.isMonsterDie = true;
    }
}