```
feat(gameplay): 调整单位属性和纹理设置并优化主角移动系统 - 修改多个纹理资源的最大尺寸从2048降至512,并添加PlayableAds平台设置 - 调整第一、二章多个单位的移动速度、攻击力和攻击持续时间参数 - 重命名精锐士兵预制体名称,移除"新"字后缀 - 降低精锐士兵的攻击力和攻击持续时间 - 为主角战斗组件添加detectRange字段,实现寻敌和攻击范围分离 - 重构主角移动系统,从点击移动改为自动巡逻模式,增加栓绳机制防止远离基地 - 实现巡逻和追击状态切换,在发现敌人时停止巡逻进行攻击 -
This commit is contained in:
1 parent
769aea30f3
commit
8d43961f67
28 files changed
+443
-125
No files matched your search
@@ -1,49 +1,91 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
/// <summary>
|
||||
/// 主角自动巡逻移动:不再支持点击地面移动(避免与拖动屏幕、建筑放置的输入冲突)。
|
||||
/// 没有敌人时在己方主建筑周围小范围来回走动,所有移动被限制在基地附近(栓绳范围)。
|
||||
/// 战斗组件发现敌人后调用 SetPatrolEnabled(false) 停止巡逻进行攻击。
|
||||
/// </summary>
|
||||
public class MainCharacterDebugMovement : MonoBehaviour
|
||||
{
|
||||
[Header("电脑调试移动")]
|
||||
[Header("巡逻移动")]
|
||||
[Min(0f)]
|
||||
public float moveSpeed = 4f;
|
||||
|
||||
[Min(0f)]
|
||||
public float clickStopDistance = 0.08f;
|
||||
public float patrolStopDistance = 0.15f;
|
||||
|
||||
[Header("移动范围")]
|
||||
public bool limitToBattlePlatform = true;
|
||||
public Vector2 xLimits = new Vector2(-7.5f, 7.5f);
|
||||
public Vector2 zLimits = new Vector2(-14f, 14f);
|
||||
[Min(0f)]
|
||||
public float patrolPause = 1.5f;
|
||||
|
||||
[Header("巡逻区域(以主建筑为锚点)")]
|
||||
[Min(0f)]
|
||||
public float patrolRadius = 5f;
|
||||
|
||||
[Min(0f)]
|
||||
public float leashRadius = 8f;
|
||||
|
||||
public string friendlyBuildingTag = "Friend";
|
||||
|
||||
private Animator animator;
|
||||
private Vector3 clickTarget;
|
||||
private bool hasClickTarget;
|
||||
private Transform baseAnchor;
|
||||
private Vector3 fallbackAnchor;
|
||||
private Vector3 patrolTarget;
|
||||
private Vector3 chaseTarget;
|
||||
private bool hasPatrolTarget;
|
||||
private bool hasChaseTarget;
|
||||
private float pauseTimer;
|
||||
private bool patrolEnabled = true;
|
||||
|
||||
public bool IsMoving => hasClickTarget;
|
||||
public bool IsMoving { get; private set; }
|
||||
|
||||
private Vector3 AnchorPosition
|
||||
{
|
||||
get
|
||||
{
|
||||
Vector3 position = baseAnchor != null ? baseAnchor.position : fallbackAnchor;
|
||||
position.y = transform.position.y;
|
||||
return position;
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
animator = GetComponent<Animator>();
|
||||
clickTarget = transform.position;
|
||||
fallbackAnchor = transform.position;
|
||||
baseAnchor = FindMainBase();
|
||||
SetWalking(false);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
HandleClickTarget();
|
||||
|
||||
if (!hasClickTarget)
|
||||
if (!patrolEnabled)
|
||||
{
|
||||
UpdateChase();
|
||||
return;
|
||||
}
|
||||
|
||||
if (pauseTimer > 0f)
|
||||
{
|
||||
pauseTimer -= Time.deltaTime;
|
||||
IsMoving = false;
|
||||
SetWalking(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 toTarget = clickTarget - transform.position;
|
||||
if (!hasPatrolTarget)
|
||||
{
|
||||
patrolTarget = GetNextPatrolPoint();
|
||||
hasPatrolTarget = true;
|
||||
}
|
||||
|
||||
Vector3 toTarget = patrolTarget - transform.position;
|
||||
toTarget.y = 0f;
|
||||
|
||||
if (toTarget.magnitude <= clickStopDistance)
|
||||
if (toTarget.magnitude <= patrolStopDistance)
|
||||
{
|
||||
hasClickTarget = false;
|
||||
hasPatrolTarget = false;
|
||||
pauseTimer = patrolPause;
|
||||
IsMoving = false;
|
||||
SetWalking(false);
|
||||
return;
|
||||
}
|
||||
@@ -51,32 +93,122 @@ public class MainCharacterDebugMovement : MonoBehaviour
|
||||
Move(toTarget.normalized);
|
||||
}
|
||||
|
||||
private void HandleClickTarget()
|
||||
private void UpdateChase()
|
||||
{
|
||||
if (!Input.GetMouseButtonDown(0) || Camera.main == null)
|
||||
if (!hasChaseTarget)
|
||||
{
|
||||
IsMoving = false;
|
||||
SetWalking(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 toTarget = chaseTarget - transform.position;
|
||||
toTarget.y = 0f;
|
||||
|
||||
if (toTarget.magnitude <= patrolStopDistance)
|
||||
{
|
||||
IsMoving = false;
|
||||
SetWalking(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 追击同样受栓绳限制,不会完全离开基地
|
||||
Move(toTarget.normalized);
|
||||
}
|
||||
|
||||
private Transform FindMainBase()
|
||||
{
|
||||
Transform firstBuilding = null;
|
||||
foreach (GameObject candidate in GameObject.FindGameObjectsWithTag(friendlyBuildingTag))
|
||||
{
|
||||
if (candidate == null || candidate.transform.root == transform.root)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (candidate.GetComponentInParent<BuildingHealth>() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 主建筑按名称优先匹配;找不到时退回第一个己方建筑
|
||||
if (candidate.name.Contains("主要") || candidate.name.Contains("基地"))
|
||||
{
|
||||
return candidate.transform;
|
||||
}
|
||||
|
||||
if (firstBuilding == null)
|
||||
{
|
||||
firstBuilding = candidate.transform;
|
||||
}
|
||||
}
|
||||
|
||||
return firstBuilding;
|
||||
}
|
||||
|
||||
private Vector3 GetNextPatrolPoint()
|
||||
{
|
||||
Vector2 offset = Random.insideUnitCircle * patrolRadius;
|
||||
return ClampToLeash(AnchorPosition + new Vector3(offset.x, 0f, offset.y));
|
||||
}
|
||||
|
||||
private Vector3 ClampToLeash(Vector3 position)
|
||||
{
|
||||
Vector3 offset = position - AnchorPosition;
|
||||
offset.y = 0f;
|
||||
if (offset.magnitude > leashRadius)
|
||||
{
|
||||
offset = offset.normalized * leashRadius;
|
||||
}
|
||||
|
||||
return AnchorPosition + offset;
|
||||
}
|
||||
|
||||
public bool IsWithinLeash(Vector3 position)
|
||||
{
|
||||
Vector3 offset = position - AnchorPosition;
|
||||
offset.y = 0f;
|
||||
return offset.magnitude <= leashRadius;
|
||||
}
|
||||
|
||||
public void SetPatrolEnabled(bool enabled)
|
||||
{
|
||||
if (patrolEnabled == enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (EventSystem.current != null && EventSystem.current.IsPointerOverGameObject())
|
||||
patrolEnabled = enabled;
|
||||
if (!enabled)
|
||||
{
|
||||
return;
|
||||
hasPatrolTarget = false;
|
||||
pauseTimer = 0f;
|
||||
IsMoving = false;
|
||||
SetWalking(false);
|
||||
}
|
||||
|
||||
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
||||
if (!Physics.Raycast(ray, out RaycastHit hit))
|
||||
else
|
||||
{
|
||||
return;
|
||||
hasChaseTarget = false;
|
||||
}
|
||||
}
|
||||
|
||||
clickTarget = hit.point;
|
||||
clickTarget.y = transform.position.y;
|
||||
hasClickTarget = true;
|
||||
public void SetChaseTarget(Vector3 position)
|
||||
{
|
||||
chaseTarget = position;
|
||||
chaseTarget.y = transform.position.y;
|
||||
hasChaseTarget = true;
|
||||
}
|
||||
|
||||
public void ClearChaseTarget()
|
||||
{
|
||||
hasChaseTarget = false;
|
||||
}
|
||||
|
||||
public void StopMovement()
|
||||
{
|
||||
hasClickTarget = false;
|
||||
hasPatrolTarget = false;
|
||||
hasChaseTarget = false;
|
||||
IsMoving = false;
|
||||
SetWalking(false);
|
||||
}
|
||||
|
||||
@@ -85,19 +217,19 @@ public class MainCharacterDebugMovement : MonoBehaviour
|
||||
direction.y = 0f;
|
||||
if (direction.sqrMagnitude <= 0.001f)
|
||||
{
|
||||
IsMoving = false;
|
||||
SetWalking(false);
|
||||
return;
|
||||
}
|
||||
|
||||
IsMoving = true;
|
||||
SetWalking(true);
|
||||
transform.position += direction * moveSpeed * Time.deltaTime;
|
||||
if (limitToBattlePlatform)
|
||||
{
|
||||
Vector3 position = transform.position;
|
||||
position.x = Mathf.Clamp(position.x, xLimits.x, xLimits.y);
|
||||
position.z = Mathf.Clamp(position.z, zLimits.x, zLimits.y);
|
||||
transform.position = position;
|
||||
}
|
||||
|
||||
// 栓绳:任何情况下都不能完全离开基地
|
||||
Vector3 clamped = ClampToLeash(transform.position);
|
||||
clamped.y = transform.position.y;
|
||||
transform.position = clamped;
|
||||
|
||||
transform.rotation = Quaternion.LookRotation(direction, Vector3.up);
|
||||
}
|
||||
@@ -109,4 +241,4 @@ public class MainCharacterDebugMovement : MonoBehaviour
|
||||
animator.SetInteger("speed", walking ? 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user