首次上传
This commit is contained in:
1 parent
2938cd4121
commit
6deaf70152
55 files changed
+14773
No files matched your search
@@ -0,0 +1,97 @@
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 标准的“点击地面移动角色”组件。
|
||||
///
|
||||
/// 用法:把本脚本挂到一个带 CharacterController 的对象上(本项目中是一个长方体 Cube)。
|
||||
/// 运行时**按住**鼠标左键(拖拽),角色会持续朝鼠标当前指向的地面点移动并平滑转向,
|
||||
/// 松开即停止;**按下瞬间**会在点击位置生成一个粒子预制体(可选),2 秒后自动销毁。
|
||||
/// 角色仅在地表高度移动(保持 y 不变)。
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(CharacterController))]
|
||||
public class ClickToMove : MonoBehaviour
|
||||
{
|
||||
[Tooltip("角色移动速度(单位/秒)")]
|
||||
[SerializeField] private float speed = 3f;
|
||||
|
||||
[Tooltip("点击地面时在点击位置动态生成的粒子预制体(需带 ParticleSystem 组件,实例化后 2 秒自动销毁)")]
|
||||
[SerializeField] private GameObject clickEffect;
|
||||
|
||||
private CharacterController _controller;
|
||||
private Vector3 _target;
|
||||
private bool _moving;
|
||||
|
||||
// “Ground” 层索引,与 ProjectSettings/TagManager.asset 中的配置一致(第 6 层)。
|
||||
private int _groundLayer = 6;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_controller = GetComponent<CharacterController>();
|
||||
_target = transform.position;
|
||||
|
||||
// 优先使用项目里命名的 “Ground” 层;若编辑器尚未刷新层名则回退到默认索引 6。
|
||||
int named = LayerMask.NameToLayer("Ground");
|
||||
if (named >= 0)
|
||||
_groundLayer = named;
|
||||
else
|
||||
Debug.LogWarning("[ClickToMove] 未找到 \"Ground\" 层,回退使用默认层索引 6。");
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
bool clicked = Input.GetMouseButtonDown(0);
|
||||
bool holding = Input.GetMouseButton(0);
|
||||
|
||||
// 按下瞬间 或 按住拖拽时,都朝当前鼠标指向的地面点更新目标;
|
||||
// 仅在“按下瞬间”生成一次点击粒子,避免按住过程中每帧重复生成。
|
||||
if (clicked || holding)
|
||||
{
|
||||
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
||||
if (Physics.Raycast(ray, out RaycastHit hit, 100f, 1 << _groundLayer))
|
||||
{
|
||||
_target = hit.point;
|
||||
_moving = true;
|
||||
if (clicked)
|
||||
SpawnClickEffect(hit.point);
|
||||
}
|
||||
}
|
||||
|
||||
// 朝目标点移动并转向
|
||||
if (!_moving) return;
|
||||
|
||||
Vector3 dir = _target - transform.position;
|
||||
dir.y = 0f; // 只在地表水平方向移动
|
||||
|
||||
if (dir.sqrMagnitude > 0.05f)
|
||||
{
|
||||
_controller.Move(dir.normalized * (speed * Time.deltaTime));
|
||||
|
||||
Vector3 facing = new Vector3(dir.x, 0f, dir.z);
|
||||
if (facing.sqrMagnitude > 0.001f)
|
||||
transform.rotation = Quaternion.Slerp(
|
||||
transform.rotation,
|
||||
Quaternion.LookRotation(facing),
|
||||
Time.deltaTime * 12f);
|
||||
}
|
||||
else
|
||||
{
|
||||
_moving = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>在点击位置动态生成粒子预制体,2 秒后自动销毁。</summary>
|
||||
private void SpawnClickEffect(Vector3 position)
|
||||
{
|
||||
if (clickEffect == null) return;
|
||||
|
||||
// 在点击位置实例化预制体
|
||||
GameObject effect = Instantiate(clickEffect, position, Quaternion.identity);
|
||||
|
||||
// 确保粒子播放(若预制体 playOnAwake 未勾选也能看到)
|
||||
ParticleSystem ps = effect.GetComponent<ParticleSystem>();
|
||||
if (ps != null) ps.Play();
|
||||
|
||||
// 延迟 2 秒后销毁
|
||||
Destroy(effect, 2f);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in new issue
Block a user