도전 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 |