ahahahahahah
This commit is contained in:
@@ -453,6 +453,8 @@ GameObject:
|
||||
- component: {fileID: 5770331367975928816}
|
||||
- component: {fileID: 4112854993683970537}
|
||||
- component: {fileID: 3240800621832008763}
|
||||
- component: {fileID: 8239948856752686218}
|
||||
- component: {fileID: 3321677048699702084}
|
||||
m_Layer: 0
|
||||
m_Name: xNPC
|
||||
m_TagString: Untagged
|
||||
@@ -491,23 +493,15 @@ MonoBehaviour:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::EnemyAI
|
||||
player: {fileID: 0}
|
||||
viewAngle: 90
|
||||
viewRadius: 20
|
||||
targetLayerMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
obstacleLayerMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
patrolPoints: []
|
||||
moveSpeed: 3
|
||||
chaseSpeed: 5
|
||||
rotateSpeed: 50
|
||||
patrolPoints: []
|
||||
patrolWaitTime: 2
|
||||
playerHasArtifact: 0
|
||||
laserPrefab: {fileID: 3965388737199864462, guid: fbec2b501d70daa4c9cb481ba53fc0b8, type: 3}
|
||||
firePoint: {fileID: 5863061020199015852}
|
||||
minShootDelay: 1
|
||||
maxShootDelay: 3
|
||||
rotateSpeed: 50
|
||||
dodgeForce: 8
|
||||
dodgeDuration: 0.5
|
||||
dodgeCooldown: 3
|
||||
@@ -575,6 +569,42 @@ MonoBehaviour:
|
||||
textDisplay: {fileID: 4454520411962799200}
|
||||
canvasGroup: {fileID: 1620994605374968907}
|
||||
bubbleRect: {fileID: 6775114823217050358}
|
||||
--- !u!114 &8239948856752686218
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7522161431095319480}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 210b37cfe4a84a34a91d0a9e58856a60, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::FieldOfView
|
||||
viewAngle: 90
|
||||
viewRadius: 20
|
||||
obstacleLayerMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 128
|
||||
targetLayerMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 256
|
||||
canSeePlayer: 0
|
||||
lastKnownPlayerPosition: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &3321677048699702084
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7522161431095319480}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 35bba55c2a743d042ab1fff35e29db50, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::AnimatorAI
|
||||
sprintThreshold: 0.8
|
||||
dampTime: 0.1
|
||||
--- !u!1001 &7561534673732472622
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
@@ -1,16 +1,251 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
using Invector;
|
||||
using System.Collections;
|
||||
|
||||
/// <summary>
|
||||
/// AnimatorAI: Đồng bộ hóa trạng thái của EnemyAI với Animator.
|
||||
/// Tích hợp Simulation Mode để giả lập animation khi chưa có logic di chuyển hoàn chỉnh.
|
||||
/// </summary>
|
||||
public class AnimatorAI : MonoBehaviour
|
||||
{
|
||||
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
||||
void Start()
|
||||
protected Animator animator;
|
||||
protected EnemyAI enemyAI;
|
||||
protected NavMeshAgent agent;
|
||||
protected Rigidbody rb;
|
||||
|
||||
[Header("Debug Settings")]
|
||||
public bool debugMode = true;
|
||||
public Color debugColor = Color.cyan;
|
||||
|
||||
[Header("Simulation Mode (Giả lập)")]
|
||||
public bool useSimulation = false; // Tích chọn để dùng thông số giả lập bên dưới
|
||||
public bool autoCycleSpeed = false; // Tự động chạy/đi bộ/đứng im theo vòng lặp
|
||||
[Range(0, 1)] public float simVerticalVelocity = 0f;
|
||||
public bool simIsSprinting = false;
|
||||
public bool simIsAiming = false;
|
||||
public int simMoveSetID = 0;
|
||||
|
||||
[Header("Movement Settings")]
|
||||
public float sprintThreshold = 0.8f;
|
||||
public float dampTime = 0.1f;
|
||||
|
||||
#region Animator Parameters (Invector Style)
|
||||
protected vAnimatorParameter isDead;
|
||||
protected vAnimatorParameter isGrounded;
|
||||
protected vAnimatorParameter isCrouching;
|
||||
protected vAnimatorParameter isStrafing;
|
||||
protected vAnimatorParameter isSliding;
|
||||
protected vAnimatorParameter isSprinting;
|
||||
protected vAnimatorParameter isAiming;
|
||||
protected vAnimatorParameter canAim;
|
||||
protected vAnimatorParameter flipAnimation;
|
||||
protected vAnimatorParameter flipEquip;
|
||||
protected vAnimatorParameter groundDistance;
|
||||
protected vAnimatorParameter groundAngle;
|
||||
protected vAnimatorParameter verticalVelocity;
|
||||
protected vAnimatorParameter moveSet_ID;
|
||||
protected vAnimatorParameter upperBody_ID;
|
||||
protected vAnimatorParameter idleRandom;
|
||||
protected vAnimatorParameter idleRandomTrigger;
|
||||
protected vAnimatorParameter randomAttack;
|
||||
protected vAnimatorParameter weakAttack;
|
||||
protected vAnimatorParameter strongAttack;
|
||||
protected vAnimatorParameter isBlocking;
|
||||
protected vAnimatorParameter attackID;
|
||||
protected vAnimatorParameter defenseID;
|
||||
protected vAnimatorParameter recoilID;
|
||||
protected vAnimatorParameter reactionID;
|
||||
protected vAnimatorParameter triggerRecoil;
|
||||
protected vAnimatorParameter triggerReaction;
|
||||
protected vAnimatorParameter hitDirection;
|
||||
protected vAnimatorParameter resetState;
|
||||
protected vAnimatorParameter reload;
|
||||
protected vAnimatorParameter cancelReload;
|
||||
protected vAnimatorParameter reloadID;
|
||||
protected vAnimatorParameter shoot;
|
||||
protected vAnimatorParameter shot_ID;
|
||||
protected vAnimatorParameter powerCharger;
|
||||
#endregion
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
|
||||
// Sử dụng GetComponentInChildren để tìm Animator ở các đối tượng con (khung Mesh)
|
||||
animator = GetComponentInChildren<Animator>();
|
||||
enemyAI = GetComponent<EnemyAI>();
|
||||
agent = GetComponent<NavMeshAgent>();
|
||||
rb = GetComponent<Rigidbody>();
|
||||
|
||||
if (animator == null)
|
||||
{
|
||||
Debug.LogError($"<color=red>[AnimatorAI]</color> KHÔNG tìm thấy Animator trên {gameObject.name} hoặc các con của nó!");
|
||||
}
|
||||
else if (debugMode)
|
||||
{
|
||||
Debug.Log($"<color=green>[AnimatorAI]</color> Đã tìm thấy Animator trên đối tượng: {animator.gameObject.name}");
|
||||
}
|
||||
|
||||
InitializeParameters();
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
protected virtual void InitializeParameters()
|
||||
{
|
||||
|
||||
if (animator == null) return;
|
||||
|
||||
isDead = new vAnimatorParameter(animator, "isDead");
|
||||
isGrounded = new vAnimatorParameter(animator, "IsGrounded");
|
||||
isCrouching = new vAnimatorParameter(animator, "IsCrouching");
|
||||
isStrafing = new vAnimatorParameter(animator, "IsStrafing");
|
||||
isSliding = new vAnimatorParameter(animator, "IsSliding");
|
||||
isSprinting = new vAnimatorParameter(animator, "IsSprinting");
|
||||
isAiming = new vAnimatorParameter(animator, "IsAiming");
|
||||
canAim = new vAnimatorParameter(animator, "CanAim");
|
||||
flipAnimation = new vAnimatorParameter(animator, "FlipAnimation");
|
||||
flipEquip = new vAnimatorParameter(animator, "FlipEquip");
|
||||
groundDistance = new vAnimatorParameter(animator, "GroundDistance");
|
||||
groundAngle = new vAnimatorParameter(animator, "GroundAngle");
|
||||
verticalVelocity = new vAnimatorParameter(animator, "VerticalVelocity");
|
||||
moveSet_ID = new vAnimatorParameter(animator, "MoveSet_ID");
|
||||
upperBody_ID = new vAnimatorParameter(animator, "UpperBody_ID");
|
||||
idleRandom = new vAnimatorParameter(animator, "IdleRandom");
|
||||
idleRandomTrigger = new vAnimatorParameter(animator, "IdleRandomTrigger");
|
||||
randomAttack = new vAnimatorParameter(animator, "RandomAttack");
|
||||
weakAttack = new vAnimatorParameter(animator, "WeakAttack");
|
||||
strongAttack = new vAnimatorParameter(animator, "StrongAttack");
|
||||
isBlocking = new vAnimatorParameter(animator, "IsBlocking");
|
||||
attackID = new vAnimatorParameter(animator, "AttackID");
|
||||
defenseID = new vAnimatorParameter(animator, "DefenseID");
|
||||
recoilID = new vAnimatorParameter(animator, "RecoilID");
|
||||
reactionID = new vAnimatorParameter(animator, "ReactionID");
|
||||
triggerRecoil = new vAnimatorParameter(animator, "TriggerRecoil");
|
||||
triggerReaction = new vAnimatorParameter(animator, "TriggerReaction");
|
||||
hitDirection = new vAnimatorParameter(animator, "HitDirection");
|
||||
resetState = new vAnimatorParameter(animator, "ResetState");
|
||||
reload = new vAnimatorParameter(animator, "Reload");
|
||||
cancelReload = new vAnimatorParameter(animator, "CancelReload");
|
||||
reloadID = new vAnimatorParameter(animator, "ReloadID");
|
||||
shoot = new vAnimatorParameter(animator, "Shoot");
|
||||
shot_ID = new vAnimatorParameter(animator, "Shot_ID");
|
||||
powerCharger = new vAnimatorParameter(animator, "PowerCharger");
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
if (animator == null) return;
|
||||
|
||||
if (useSimulation)
|
||||
{
|
||||
RunSimulation();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enemyAI == null || agent == null) return;
|
||||
UpdateMovementParameters();
|
||||
UpdateCombatParameters();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void RunSimulation()
|
||||
{
|
||||
// 1. Giả lập tốc độ di chuyển
|
||||
if (autoCycleSpeed)
|
||||
{
|
||||
// Tạo vòng lặp tốc độ từ 0 đến 1 dùng hàm Sin
|
||||
simVerticalVelocity = Mathf.Abs(Mathf.Sin(Time.time * 0.5f));
|
||||
simIsSprinting = simVerticalVelocity > sprintThreshold;
|
||||
}
|
||||
|
||||
SetFloat(verticalVelocity, simVerticalVelocity, "SIM: VerticalVelocity");
|
||||
SetBool(isSprinting, simIsSprinting, "SIM: IsSprinting");
|
||||
SetBool(isGrounded, true, "SIM: IsGrounded"); // Luôn giả lập trên mặt đất
|
||||
|
||||
// 2. Giả lập chiến đấu
|
||||
SetBool(isAiming, simIsAiming, "SIM: IsAiming");
|
||||
SetInt(moveSet_ID, simMoveSetID, "SIM: MoveSet_ID");
|
||||
SetBool(canAim, simIsAiming, "SIM: CanAim");
|
||||
}
|
||||
|
||||
protected virtual void UpdateMovementParameters()
|
||||
{
|
||||
bool grounded = agent.isOnNavMesh || agent.enabled;
|
||||
SetBool(isGrounded, grounded, "IsGrounded");
|
||||
|
||||
float speed = agent.velocity.magnitude / enemyAI.moveSpeed;
|
||||
SetFloat(verticalVelocity, speed, "VerticalVelocity");
|
||||
|
||||
bool sprinting = agent.velocity.magnitude > (enemyAI.moveSpeed * sprintThreshold);
|
||||
SetBool(isSprinting, sprinting, "IsSprinting");
|
||||
|
||||
bool isDodging = !agent.enabled && !rb.isKinematic;
|
||||
SetBool(flipAnimation, isDodging, "FlipAnimation (Dodge)");
|
||||
}
|
||||
|
||||
protected virtual void UpdateCombatParameters()
|
||||
{
|
||||
bool aiming = enemyAI.playerHasArtifact && agent.isStopped;
|
||||
SetBool(isAiming, aiming, "IsAiming");
|
||||
|
||||
int moveID = enemyAI.playerHasArtifact ? 1 : 0;
|
||||
SetInt(moveSet_ID, moveID, "MoveSet_ID");
|
||||
|
||||
SetBool(canAim, enemyAI.playerHasArtifact, "CanAim");
|
||||
}
|
||||
|
||||
#region Optimized Setters with Debug
|
||||
|
||||
protected void SetBool(vAnimatorParameter param, bool value, string name)
|
||||
{
|
||||
if (param.isValid)
|
||||
{
|
||||
bool current = animator.GetBool(param);
|
||||
if (current != value)
|
||||
{
|
||||
animator.SetBool(param, value);
|
||||
if (debugMode) Debug.Log($"<color=cyan>[AnimDebug]</color> {gameObject.name}: <b>{name}</b> -> {value}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void SetFloat(vAnimatorParameter param, float value, string name)
|
||||
{
|
||||
if (param.isValid)
|
||||
{
|
||||
animator.SetFloat(param, value, dampTime, Time.deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
protected void SetInt(vAnimatorParameter param, int value, string name)
|
||||
{
|
||||
if (param.isValid)
|
||||
{
|
||||
int current = animator.GetInteger(param);
|
||||
if (current != value)
|
||||
{
|
||||
animator.SetInteger(param, value);
|
||||
if (debugMode) Debug.Log($"<color=orange>[AnimDebug]</color> {gameObject.name}: <b>{name}</b> -> {value}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper Methods (Triggers)
|
||||
|
||||
public virtual void SetAnimatorTrigger(vAnimatorParameter trigger, string name = "Trigger")
|
||||
{
|
||||
if (trigger.isValid)
|
||||
{
|
||||
if (debugMode) Debug.Log($"<color=yellow>[AnimDebug]</color> {gameObject.name}: Kích hoạt <b>{name}</b>");
|
||||
StartCoroutine(SetTriggerRoutine(trigger));
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator SetTriggerRoutine(int targetHash)
|
||||
{
|
||||
animator.SetTrigger(targetHash);
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
animator.ResetTrigger(targetHash);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user