도전 5번 코드 입니다

Unity3D 2022. 1. 26. 15:34
반응형
using System.Collections;
using UnityEngine;
using UnityEngine.Events;

public class Hero : MonoBehaviour
{
    public enum eAttackType { 
        None, Attack01, Attack02
    }
    
    public GameObject model;
    public float attackDelay = 0.5f;
    public float impactOffset = 0.5f;
    private float hp;
    public float maxHp;
    public float damage;
    public float attackRange;

    private Animator anim;
    private Coroutine routine;
    public UnityAction<eAttackType> OnAttackImpact;
    private Slime target;
    private UnityAction OnMoveComplete;

    void Start()
    {
        this.anim = this.model.GetComponent<Animator>();
        this.hp = this.maxHp;
        this.OnMoveComplete = () => {
            this.Attack(this.target);
        };
    }

    public void Attack(Slime target) {
        this.target = target;
        if (this.routine != null) StopCoroutine(this.routine);
        this.routine = StartCoroutine(this.AttackRoutine());
    }

    private IEnumerator AttackRoutine()
    {
        while (true) {
            //->
            if (HasTarget())
            {
                //check attackrange 
                if (this.CanAttack())
                {
                    yield return StartCoroutine(this.Attack01Routine());
                }
                else 
                {
                    //move 
                    this.routine = StartCoroutine(this.MoveToTarget());
                    yield break;
                }
                
            }
            else 
            {
                this.Idle();
                break;
            }

            if (this.HasTarget()) {
                //check attackrange 
                if (this.CanAttack())
                {
                    yield return StartCoroutine(this.Attack02Routine());
                }
                else
                {
                    //move 
                    this.routine = StartCoroutine(this.MoveToTarget());
                    yield break;
                }
            }
            else
            {
                this.Idle();
                break;
            }

        }
    }

    private IEnumerator MoveToTarget() {
        
        this.transform.LookAt(this.target.transform);

        //run play animation 
        this.anim.Play("RunForwardBattle", -1, 0);

        while (true) {

            this.transform.Translate(Vector3.forward * 1.0f * Time.deltaTime);
            
            if (CanAttack()) {

                //play idle animation (optional)

                this.OnMoveComplete();
                yield break;
            }

            yield return null;
        }
    }

    public bool CanAttack() {
        var distance = Vector3.Distance(this.target.transform.position, this.transform.position);
        return this.attackRange >= distance;
    }

    public void Idle() {
        this.anim.Play("Idle_Battle", -1, 0);
    }

    public void SetTarget(Slime target) {
        this.target = target;
    }

    private IEnumerator Attack02Routine() {
        this.anim.Play("Attack02", -1, 0);

        yield return null;
        var length = this.GetClipLength();

        var impactTime = 0.533f - impactOffset;
        length = this.GetClipLength();
        impactTime = 0.399f - impactOffset;
        yield return new WaitForSeconds(impactTime);

        //타겟에게 피해를 입힙니다 
        this.target.Hit(this.damage);

        //이벤트 발생  
        this.OnAttackImpact(eAttackType.Attack02);
        yield return new WaitForSeconds(length - impactTime);

        this.Idle();

        //attack delay 
        yield return new WaitForSeconds(this.attackDelay);
    }
    private IEnumerator Attack01Routine() {
        this.anim.Play("Attack01", -1, 0);

        yield return null;

        var length = this.GetClipLength();

        var impactTime = 0.533f - impactOffset;

        yield return new WaitForSeconds(impactTime);
        //타겟에게 피해를 입힙니다 
        this.target.Hit(this.damage);

        //이벤트 발생
        this.OnAttackImpact(eAttackType.Attack01);
        yield return new WaitForSeconds(length - impactTime);   //attack delay 
    }

    private bool HasTarget() {
        return this.target != null;
    }

    private float GetClipLength() {
        AnimatorClipInfo[] clipInfos = this.anim.GetCurrentAnimatorClipInfo(0);
        AnimationClip clip = clipInfos[0].clip;
        return clip.length;
    }

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        float corners = 11; // How many corners the circle should have
        //float size = 10; // How wide the circle should be
        Vector3 origin = transform.position; // Where the circle will be drawn around
        Vector3 startRotation = transform.right * this.attackRange; // Where the first point of the circle starts
        Vector3 lastPosition = origin + startRotation;
        float angle = 0;
        while (angle <= 360)
        {
            angle += 360 / corners;
            Vector3 nextPosition = origin + (Quaternion.Euler(0, angle, 0) * startRotation);
            Gizmos.DrawLine(lastPosition, nextPosition);
            //Gizmos.DrawSphere(nextPosition, 1);

            lastPosition = nextPosition;
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class Slime : MonoBehaviour
{
    Animator anim;
    Coroutine routine;
    public float maxHp;
    private float hp;
    public UnityAction OnDieAction;

    void Start()
    {
        this.anim = this.GetComponent<Animator>();
        this.hp = this.maxHp;
    }

    public void Hit(float damage)
    {
        this.hp -= damage;

        if (this.hp <= 0)
        {
            this.hp = 0;
            //die 
            this.Die();
        }
        else {
            if (this.routine != null)
            {
                StopCoroutine(this.routine);
            }
            this.routine = StartCoroutine(this.HitRoutine());
        }
    }

    private IEnumerator HitRoutine() {
        this.anim.Play("GetHit", -1, 0);

        yield return new WaitForSeconds(0.833f);

        this.anim.Play("IdleBattle", -1, 0);
    }

    private void Die() {
        Debug.Log("Die!!!");
        this.OnDieAction();

        //play animation 
        this.anim.Play("Die", -1, 0);

        //wait for die animation 
        this.StartCoroutine(this.WaitForSec(1.33f, () =>
        {
            //destroy gameobject 
            Destroy(this.gameObject);
        }));
        
    }

    private IEnumerator WaitForSec(float sec, System.Action callback) {
        yield return new WaitForSeconds(sec);
        callback();
    }
        

}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Challenge04Main : MonoBehaviour
{
    public Hero hero;
    public Slime slime;
    public Button btnAttack;

    // Start is called before the first frame update
    void Start()
    {
        this.slime.OnDieAction = () => {
            this.hero.SetTarget(null);
        };

        this.hero.OnAttackImpact = (impactType) => {
            switch (impactType) {
                case Hero.eAttackType.Attack01:
                    
                    break;
                case Hero.eAttackType.Attack02:
                    
                    break;
            }
        };
        this.btnAttack.onClick.AddListener(() => {
            this.hero.Attack(this.slime);
        });
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
using UnityEngine;
using System.Collections;
#if UNITY_EDITOR
using UnityEditor;
#endif
// adapted from http://wiki.unity3d.com/index.php/DrawArrow 


public enum ArrowType
{
	Default,
	Thin,
	Double,
	Triple,
	Solid,
	Fat,
	ThreeD,
}

public static class DrawArrow
{
	public static void ForGizmo(Vector3 pos, Vector3 direction, Color? color = null, bool doubled = false, float arrowHeadLength = 0.2f, float arrowHeadAngle = 20.0f)
	{
		Gizmos.color = color ?? Color.white;

		//arrow shaft
		Gizmos.DrawRay(pos, direction);

		if (direction != Vector3.zero)
		{
			//arrow head
			Vector3 right = Quaternion.LookRotation(direction) * Quaternion.Euler(0, 180 + arrowHeadAngle, 0) * new Vector3(0, 0, 1);
			Vector3 left = Quaternion.LookRotation(direction) * Quaternion.Euler(0, 180 - arrowHeadAngle, 0) * new Vector3(0, 0, 1);
			Gizmos.DrawRay(pos + direction, right * arrowHeadLength);
			Gizmos.DrawRay(pos + direction, left * arrowHeadLength);
		}
	}

	public static void ForDebug(Vector3 pos, Vector3 direction, float duration = 0.5f, Color? color = null, ArrowType type = ArrowType.Default, float arrowHeadLength = 0.2f, float arrowHeadAngle = 30.0f, bool sceneCamFollows = false)
	{
		Color actualColor = color ?? Color.white;
		duration = duration / Time.timeScale;

		float width = 0.01f;

		Vector3 directlyRight = Vector3.zero;
		Vector3 directlyLeft = Vector3.zero;
		Vector3 directlyBack = Vector3.zero;
		Vector3 headRight = Vector3.zero;
		Vector3 headLeft = Vector3.zero;

		if (direction != Vector3.zero)
		{
			directlyRight = Quaternion.LookRotation(direction) * Quaternion.Euler(0, 180 + 90, 0) * new Vector3(0, 0, 1);
			directlyLeft = Quaternion.LookRotation(direction) * Quaternion.Euler(0, 180 - 90, 0) * new Vector3(0, 0, 1);
			directlyBack = Quaternion.LookRotation(direction) * Quaternion.Euler(0, 180, 0) * new Vector3(0, 0, 1);
			headRight = Quaternion.LookRotation(direction) * Quaternion.Euler(0, 180 + arrowHeadAngle, 0) * new Vector3(0, 0, 1);
			headLeft = Quaternion.LookRotation(direction) * Quaternion.Euler(0, 180 - arrowHeadAngle, 0) * new Vector3(0, 0, 1);
		}

		//draw arrow head
		Debug.DrawRay(pos + direction, headRight * arrowHeadLength, actualColor, duration);
		Debug.DrawRay(pos + direction, headLeft * arrowHeadLength, actualColor, duration);

		switch (type)
		{
			case ArrowType.Default:
				Debug.DrawRay(pos, direction, actualColor, duration); //draw center line
				break;
			case ArrowType.Double:
				Debug.DrawRay(pos + directlyRight * width, direction * (1 - width), actualColor, duration); //draw line slightly to right
				Debug.DrawRay(pos + directlyLeft * width, direction * (1 - width), actualColor, duration); //draw line slightly to left

				//draw second arrow head
				Debug.DrawRay(pos + directlyBack * width + direction, headRight * arrowHeadLength, actualColor, duration);
				Debug.DrawRay(pos + directlyBack * width + direction, headLeft * arrowHeadLength, actualColor, duration);

				break;
			case ArrowType.Triple:
				Debug.DrawRay(pos, direction, actualColor, duration); //draw center line
				Debug.DrawRay(pos + directlyRight * width, direction * (1 - width), actualColor, duration); //draw line slightly to right
				Debug.DrawRay(pos + directlyLeft * width, direction * (1 - width), actualColor, duration); //draw line slightly to left
				break;
			case ArrowType.Fat:
				break;
			case ArrowType.Solid:
				int increments = 20;
				for (int i = 0; i < increments; i++)
				{
					float displacement = Mathf.Lerp(-width, +width, i / (float)increments);
					//draw arrow body
					Debug.DrawRay(pos + directlyRight * displacement, direction, actualColor, duration); //draw line slightly to right
					Debug.DrawRay(pos + directlyLeft * displacement, direction, actualColor, duration); //draw line slightly to left
																										//draw arrow head
					Debug.DrawRay((pos + direction) + directlyRight * displacement, headRight * arrowHeadLength, actualColor, duration);
					Debug.DrawRay((pos + direction) + directlyRight * displacement, headLeft * arrowHeadLength, actualColor, duration);
				}
				break;
			case ArrowType.Thin:
				Debug.DrawRay(pos, direction, actualColor, duration); //draw center line
				break;
			case ArrowType.ThreeD:
				break;
		}

		/*#if UNITY_EDITOR
			//snap the Scene view camera to a spot where it is looking directly at this arrow.
				if (sceneCamFollows)
					SceneViewCameraFollower.activateAt(pos + direction, duration, "_arrow");
		#endif*/
	}

	public static void randomStar(Vector3 center, Color color)
	{
		//special: refuse to draw at 0,0.
		if (center == Vector3.zero) return;
		for (int i = 0; i < 2; i++)
			DrawArrow.ForGizmo(center, UnityEngine.Random.onUnitSphere * 1, color, false, 0.1f, 30.0f);
	}

	public static void comparePositions(Transform t1, Transform t2)
	{
		//direct from one to the other:
		ForDebug(t1.position, t2.position - t1.position);

		//direction
		//Vector3 moveDirection = (t2.position-t1.position).normalized;
	}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DropItem : MonoBehaviour
{
    public float distance = 0.5f;
    public GameObject model;
    private Rigidbody rigid;
    public float upForce = 200f;
    void Awake()
    {
        this.rigid = this.GetComponent<Rigidbody>();
    }

    public void Init(Vector3 initPos) {
        startTime = Time.time;
        this.transform.position = initPos;
        this.rigid.AddForce(Vector3.up * upForce);

        StartCoroutine(this.WaitForDrop(() => {
            Destroy(this.rigid);
            Debug.Log("drop complete!");
        }));
    }
    float startTime;
    public float duration = 5f;
    public float rotSpeed = 2.5f;
    bool isComplete = false;
    IEnumerator WaitForDrop(System.Action callback) {
        
        while (true) {
            if (isComplete) break;
            yield return null;

            if (this.rigid.velocity.y < 0)
            {
                Ray ray = new Ray(this.transform.position, -this.transform.up * this.distance);
                Debug.DrawRay(ray.origin, ray.direction * distance, Color.red);

                RaycastHit hit;
                if (Physics.Raycast(ray, out hit, this.distance))
                {
                    if (hit.collider.tag.Equals("Ground"))
                    {
                        Debug.Log("!");
                        Quaternion q = new Quaternion();
                        q.SetFromToRotation(this.transform.forward, Vector3.up);

                        while (true) {    
                            float t = (Time.time - startTime) / duration;
                            this.transform.rotation = Quaternion.Lerp(this.transform.rotation, q, this.rotSpeed * t );
                            yield return null;

                            var lhs = this.transform.forward;
                            var rhs = Vector3.forward;
                            DrawArrow.ForDebug(this.transform.position, lhs, 0.1f, Color.red, ArrowType.Solid);

                            DrawArrow.ForDebug(Vector3.zero, rhs, 0.1f, Color.blue, ArrowType.Solid);

                            //Debug.LogFormat("{0}, {1}", Vector3.Dot(lhs, rhs), Vector3.Dot(lhs, rhs) == 0);
                            Debug.Log(this.rigid.velocity);

                            if (Vector3.Dot(lhs, rhs) <= 0.1f)
                            {
                                this.isComplete = true;
                                break;
                            }
                        }
                    }
                }
            }
        }
        callback();

    }
}
반응형

'Unity3D' 카테고리의 다른 글

HudText (damage text), world to screen position  (0) 2022.02.17
Quaternion.SetLookRotation  (0) 2022.01.26
Overview UIBuidler 1.0.0-preview.18  (0) 2021.11.08
Day - 11. UI Toolkit 살펴 보기 with UI Builder  (0) 2021.11.08
Free Unity Asset 2021  (0) 2021.11.07
: