public void InitState() { stateMachine = gameObject.AddComponent <StateMachine>(); List <SMEvent> events = new List <SMEvent>(); Dictionary <string, Func <SMEvent, bool> > callbacks = new Dictionary <string, Func <SMEvent, bool> >(); MonMoveState moveState = new MonMoveState(); moveState.statemachine = stateMachine; moveState.monCtrl = this; moveState.smEvent = new SMEvent("move", new List <string>() { "attack" }, "move"); events.Add(moveState.smEvent); moveState.SetEventArray(ref callbacks); MonAttackState attackState = new MonAttackState(); attackState.statemachine = stateMachine; attackState.monCtrl = this; attackState.smEvent = new SMEvent("attack", new List <string>() { "move" }, "attack"); events.Add(attackState.smEvent); attackState.SetEventArray(ref callbacks); string initial = "move"; stateMachine.SetupState(events, callbacks, initial, "", false); }
//Update에서 판단 void Update() { //위치 검사용 벡터 계산 trToPlayerTrVector = Vector3.Normalize(playerTr.position - tr.position); //Debug.DrawRay(sightRay.origin, sightRay.direction * sightLengthRange, Color.yellow); //레이 디버깅 //죽으면 판단 중지 if (!isDie) { //딜레이면 판단 중지 if (!isInDelay) { //////시야 판단 //시야 레이 발사 sightVector = Vector3.Normalize(SightRayEndPos.position - sightRayStartPos.position); sightRay = new Ray(sightRayStartPos.position, sightVector); //각도 계산 //sightAngle = Vector2.Angle(new Vector2(sightRayStartPos.forward.z, sightRayStartPos.forward.x), new Vector2(sightVector.z, sightVector.x)); sightAngle = Vector3.Angle(sightRayStartPos.position, SightRayEndPos.position); //시야 안에 플레이어가 있는가 판단 if (sightAngle < sightAngleRange) { if (Physics.Raycast(sightRay, out hit, sightLengthRange, inSightLayerMask)) { if (hit.distance < sightLengthRange) { if (hit.collider.tag == Tags.Player) { isInSight = true; //발견 Debug.DrawRay(sightRay.origin, sightRay.direction * sightLengthRange, Color.yellow); //레이 디버깅 print("시야 안"); } else { isInSight = false; Debug.DrawRay(sightRay.origin, sightRay.direction * sightLengthRange, Color.red); //레이 디버깅 print("시야 밖"); } } else { isInSight = false; Debug.DrawRay(sightRay.origin, sightRay.direction * sightLengthRange, Color.red); //레이 디버깅 print("시야 밖"); } } else { isInSight = false; Debug.DrawRay(sightRay.origin, sightRay.direction * sightLengthRange, Color.red); //레이 디버깅 print("시야 밖"); } } else { isInSight = false; Debug.DrawRay(sightRay.origin, sightRay.direction * sightLengthRange, Color.red); //레이 디버깅 print("시야 밖"); } print("hit " + hit.distance); //////행동 판단 if (isInSight) //시야 안에 있다 { float distance = Vector3.Distance(tr.position, playerTr.position); //플레이어와의 거리 print(distance); //앞발찍기 범위 내 앞발찍기 if (distance < forefootPressRange) { monState = MonState.Attack; monAttackState = MonAttackState.ForefootPress; print("앞발"); } //점프공격 범위 내 점프공격 else if ((distance > jumpAttkMinRange) && (distance < jumpAttkMaxRange)) { monState = MonState.Attack; monAttackState = MonAttackState.JumpAttack; print("점프"); } //공격 범위 외 플레이어 주시 else if (distance > maxAttackRange) { monState = MonState.Tracking; monTrackingState = MonTrackingState.Look; //주시해오 print("주시"); } lastPlayerPos = playerTr.position; //플레이어 마지막 위치 변경 } else //시야 안에 없다 { float distance = Vector3.Distance(tr.position, lastPlayerPos); //예상 위치와의 거리 print(distance); //예상위치에 도달했다 if (distance < guessFindedRange) { monState = MonState.Detection; monDetectionState = MonDetectionState.Idle; print("대기"); } //예상 위치 공격 범위 안 else if (distance < guessAttackRange) { monState = MonState.Attack; monAttackState = MonAttackState.BodyPress; print("바디"); } else { monState = MonState.Detection; monDetectionState = MonDetectionState.Lookaround; print("두리번"); } } //다음 판단까지 딜레이 isInDelay = true; } else { //////딜레이 타이머 delayTimeCounter += Time.deltaTime; if (delayTimeCounter > delayTime) { isInDelay = false; delayTimeCounter = 0.0f; } } } //////HP가 0 이하 시 사망처리 if (HP <= 0) { DieMonster(); } }