Zombie.ts
Zepeto 2022. 3. 31. 00:32반응형
import { ZepetoScriptBehaviour } from "ZEPETO.Script";
import {
Vector3,
Transform,
Coroutine,
Animator,
WaitForSeconds,
Time,
Mathf,
Quaternion,
CapsuleCollider,
Object,
GameObject,
SkinnedMeshRenderer,
Color,
Random,
} from "UnityEngine";
import { Slider } from "UnityEngine.UI";
import { NavMesh, NavMeshAgent, NavMeshHit } from "UnityEngine.AI";
import { isForInStatement } from "typescript";
import RaycastPerception3D from "./RaycastPerception3D";
import { UnityEvent$1, UnityEvent } from "UnityEngine.Events";
export default class Zombie extends ZepetoScriptBehaviour {
//public target: GameObject;
public slider : Slider;
public agent: NavMeshAgent;
private routine: Coroutine;
private anim: Animator;
private moveTargetPosition: Vector3;
public maxHp: float;
public hp: float;
public dieEvent: UnityEvent;
public attackEvent : UnityEvent;
private rayPerception3D: RaycastPerception3D;
public Init(initPos: Vector3, initHp: float) {
this.dieEvent = new UnityEvent();
this.attackEvent = new UnityEvent();
//this.target = target;
this.transform.position = initPos;
this.maxHp = initHp;
this.hp = this.maxHp;
//console.log(this.target);
this.agent = this.GetComponent<NavMeshAgent>();
this.anim = this.GetComponent<Animator>();
//console.log(this.agent);
var renderer =
this.gameObject.GetComponentInChildren<SkinnedMeshRenderer>();
this.rayPerception3D = this.GetComponent<RaycastPerception3D>();
this.rayPerception3D.Init();
this.rayPerception3D.AddTag("Player");
// console.log("rayPerception3D ---> " + this.rayPerception3D);
// console.log(
// "rayPerception3D.triggerTargetEvent ---> " +
// this.rayPerception3D.triggerTargetEvent
// );
this.rayPerception3D.triggerTargetEvent.AddListener((target) => {
// console.log("target: " + target);
if (target != null) {
var dis = Vector3.Distance(
target.transform.position,
this.transform.position
);
if (dis <= 1.1) {
var state = this.anim.GetInteger("State");
//console.log("state---->" + state);
if (state != 2) {
//공격 상태라면 패스
this.MoveStop(); //멈추고
this.transform.LookAt(target.transform); //바라보고
// console.log("attack!");
this.anim.speed = 4;
this.anim.SetInteger("State", 2); //공격 애니메이션
//this.anim.Play("zombie_attack", -1, 0); //리셋 애니메이션 그리고 플레이
if (this.routine != null) this.StopCoroutine(this.routine);
//그리고 잠시후 Idle
this.routine = this.StartCoroutine(this.WaitForAttack());
}else{
// console.log("state---->" + state);
}
} else {
this.Move(target.transform.position);
}
} else {
//target is null
this.MoveAny();
}
});
}
*WaitForAttack() {
//공격 속도 4배 하면 0.412
yield new WaitForSeconds(0.65/this.anim.speed); //1배속일때 0.65
this.attackEvent.Invoke();
yield new WaitForSeconds(1.0/this.anim.speed);
this.anim.speed = 1;
this.anim.SetInteger("State", 0);
//console.log('attack complete');
}
public MoveAny() {
var tpos: Vector3 = this.RandomNavSphere(20);
this.Move(tpos);
}
// public FindTarget() {
// var players = GameObject.FindGameObjectsWithTag("Player");
// console.log(`[FindTarget] : players : ${players.length}`);
// var min = 1000000;
// var newTarget = null;
// for (var i = 0; i < players.length; i++) {
// var player = players[i];
// var dis = Vector3.Distance(
// player.transform.position,
// this.transform.position
// );
// if (min > dis) {
// min = dis;
// newTarget = player.transform;
// }
// }
// if (newTarget != null) {
// console.log(`nearest target: ${newTarget.name}`);
// } else {
// console.log("target is null...");
// }
// return newTarget;
// }
public IsDie() {
return this.hp <= 0;
}
public Move(tpos) {
this.agent.ResetPath();
this.agent.isStopped = false;
this.agent.updatePosition = true;
this.agent.updateRotation = true;
this.agent.speed = 1;
this.transform.LookAt(tpos);
this.agent.SetDestination(tpos);
if (this.routine != null) this.StopCoroutine(this.routine);
this.routine = this.StartCoroutine(
this.MoveRoutine(tpos, () => {
// check distance
})
);
// this.NavigateStart();
// this.moveTargetPosition = this.target.position;
// //this.anim.Play("zombie_walk_forward");
// this.anim.SetInteger("State", 1);
// this.agent.SetDestination(this.moveTargetPosition);
// if (this.routiune != null) this.StopCoroutine(this.routiune);
// this.routiune = this.StartCoroutine(
// this.MoveRoutine((nearTarget) => {
// console.log(`nearTarget: ${nearTarget}`);
// if (nearTarget) {
// this.Attack();
// } else {
// console.log("----------------- idle -----------------");
// this.NavigateStop();
// this.anim.SetInteger("State", 0);
// //this.anim.Play("zombie_idle");
// // //this.Invoke("Move", 1.5);
// this.StartCoroutine(this.WaitForMove(1.5));
// }
// })
// );
}
// *WaitForMove(sec: float) {
// yield new WaitForSeconds(sec);
// this.Move();
// }
public MoveStop() {
this.anim.speed = 1.0;
this.agent.ResetPath();
this.agent.isStopped = true;
this.agent.updatePosition = false;
this.agent.updateRotation = false;
this.agent.velocity = Vector3.zero;
this.agent.speed = 0;
}
public Hit(damage: float) {
if(this.IsDie()) return;
this.hp -= damage;
//console.log(this.hp + " / " + this.maxHp);
if (this.hp <= 0) {
this.hp = 0;
this.UpdateHpGauge();
this.rayPerception3D.enabled = false;
if (this.routine != null) this.StopCoroutine(this.routine);
this.MoveStop();
this.GetComponent<CapsuleCollider>().enabled = false;
this.anim.SetTrigger("Dead");
this.StartCoroutine(this.DieRoutine());
}else{
this.UpdateHpGauge();
}
}
UpdateHpGauge()
{
var per = this.hp / this.maxHp;
console.log(per);
this.slider.value = per;
}
*DieRoutine() {
yield new WaitForSeconds(1.6);
//this.dieEvent.Invoke();
this.StopAllCoroutines();
Object.Destroy(this.gameObject);
}
public Attack(target) {
// console.log(
// `[Attack] target: ${target}, ${target.name}, ${target.position}`
// );
//사거리 체크
var dis = Vector3.Distance(
target.transform.position,
this.transform.position
);
//console.log(dis);
if (dis <= 1.1) {
} else if (dis < 3) {
} else {
//너무 멀면 아무대나로 이동
var tpos: Vector3 = this.RandomNavSphere(20);
this.Move(tpos);
}
//방법 2
// var dir: Vector3 = this.target.position - this.transform.position;
// var angle = Mathf.Atan2(dir.x, dir.z) * Mathf.Rad2Deg;
// this.transform.rotation = Quaternion.AngleAxis(angle, Vector3.up);
//방법 3
// var relative: Vector3 = this.transform.InverseTransformPoint(
// this.target.position
// );
// var angle = Mathf.Atan2(relative.x, relative.z) * Mathf.Rad2Deg;
// this.transform.Rotate(new Vector3(0, angle, 0));
//this.anim.Play("zombie_attack", -1, 0); //reset anim
// this.anim.SetInteger("State", 2);
// if (this.routiune != null) this.StopCoroutine(this.routiune);
// this.routiune = this.StartCoroutine(
// this.AttackRoutine(() => {
// console.log("attack complete!");
// //this.anim.Play("zombie_idle", -1, 0); //reset anim
// //this.Move();
// this.anim.SetInteger("State", 0);
// //this.anim.Play("zombie_idle", -1, 0); //reset anim
// //find target
// var playerGo = GameObject.FindGameObjectWithTag("Player");
// var dis = Vector3.Distance(
// playerGo.transform.position,
// this.transform.position
// );
// if (dis <= 1.1) {
// this.StartCoroutine(this.WaitForAttackDelay(0.5));
// } else {
// this.Move();
// }
// })
// );
}
*MoveRoutine(tpos, callback) {
this.anim.speed = 5;
this.anim.SetInteger("State", 1);
while (true) {
var dis: float = Vector3.Distance(tpos, this.transform.position);
//console.log(dis);
if (dis <= 1.1) {
break;
}
yield null;
}
this.anim.SetInteger("State", 0);
this.MoveStop();
//console.log("----------> move complete");
callback();
}
RandomNavSphere(dist: float) {
var dir = Random.insideUnitSphere;
dir.x *= dist;
dir.y *= dist;
dir.z *= dist;
let hit = $ref<NavMeshHit>();
NavMesh.SamplePosition(dir, hit, dist, 1);
return $unref(hit).position;
}
// *WaitForAttackDelay(delay: float) {
// yield new WaitForSeconds(delay);
// this.Attack();
// }
*AttackRoutine(callback) {
yield new WaitForSeconds(1.5);
callback();
}
//이동중 언제라도 타겟을 공격할수 있는 사거리라면 즉시 공격한다
// *MoveRoutine(callback) {
// var nearTarget: bool;
// while (true) {
// if (this.target == null) break;
// var dis = Vector3.Distance(
// this.transform.position,
// this.moveTargetPosition
// );
// var dis2 = Vector3.Distance(
// this.transform.position,
// this.target.position
// );
// if (dis2 <= 1.1) {
// nearTarget = true;
// break;
// }
// // console.log(dis);
// if (dis <= 1.1) {
// if (dis2 <= 1.1) {
// nearTarget = true;
// } else {
// nearTarget = false;
// }
// break;
// }
// yield null;
// }
// console.log("move complete");
// callback(nearTarget);
// }
private extraRotSpeed = 5.0;
Update() {
// var lookRotation: Vector3 =
// this.agent.steeringTarget - this.transform.position;
// this.transform.rotation = Quaternion.Slerp(
// this.transform.rotation,
// Quaternion.LookRotation(lookRotation),
// this.extraRotSpeed * Time.deltaTime
// );
}
}
반응형
'Zepeto' 카테고리의 다른 글
제페토 월드 만들기 (회전 동기화) (0) | 2022.04.11 |
---|---|
찰칵 (0) | 2022.03.31 |
zepeto world orientation horizontal (0) | 2022.03.25 |
zepeto-multiplay-example (0) | 2022.03.25 |
zepeto-script-sample (0) | 2022.03.25 |