Unity GrabPack控制器脚本帮助
using UnityEngine;
public class GrabPackController : MonoBehaviour
{
// 手臂状态Enum
public enum HandState { Idle, Shooting, Returning }
// 头的变换
[Header("Hands")]
public Transform blueHand;
public Transform redHand;
// 原点变换
[Header("Origins")]
public Transform blueOrigin;
public Transform redOrigin;
// 射击点变换
[Header("Shoot Points")]
public Transform blueShootPoint;
public Transform redShootPoint;
// 手枪变换
[Header("Guns")]
public Transform blueGun;
public Transform redGun;
// 线条渲染器
[Header("Line Renderers")]
public LineRenderer blueLine;
public LineRenderer redLine;
// 设定
[Header("Settings")]
public float shootDistance = 15f;
public float speed = 25f;
public float returnSpeed = 30f;
// 手臂状态
private HandState blueState = HandState.Idle;
private HandState redState = HandState.Idle;
// 目标点
private Vector3 blueTarget;
private Vector3 redTarget;
// 抓取物体
private GameObject blueGrabbed;
private GameObject redGrabbed;
// 主相机
private Camera cam;
// 手枪原位本地位置
private Vector3 blueGunStartLocalPos;
private Vector3 redGunStartLocalPos;
// 用于开始
private void Start()
{
cam = Camera.main;
ResetBlue();
ResetRed();
// 保存本地位置(重要)
blueGunStartLocalPos = blueGun.localPosition;
redGunStartLocalPos = redGun.localPosition;
}
// 用于更新
private void Update()
{
// 只有在空闲时才能射击
if (Input.GetMouseButtonDown(0) && blueState == HandState.Idle)
ShootBlue();
if (Input.GetMouseButtonDown(1) && redState == HandState.Idle)
ShootRed();
HandleBlue();
HandleRed();
UpdateGunRotation();
UpdateLines();
}
// 啟動藍色手臂
void ShootBlue()
{
if (cam == null) return;
blueGrabbed = null;
// 射击点对齐
Ray ray = cam.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
RaycastHit hit;
// Raycast距离
if (Physics.Raycast(ray, out hit, shootDistance))
{
blueTarget = hit.point;
// 检测是哪个物体
if (hit.collider.CompareTag("Grabbable"))
blueGrabbed = hit.collider.gameObject;
}
else
{
blueTarget = ray.origin + ray.direction * shootDistance;
}
blueState = HandState.Shooting;
}
// 处理蓝色手臂
void HandleBlue()
{
switch (blueState)
{
case HandState.Shooting:
// 把手臂移动到目标点
blueHand.position = Vector3.MoveTowards(blueHand.position, blueTarget, speed * Time.deltaTime);
// 到达目标点时射击结束
if (Vector3.Distance(blueHand.position, blueTarget) < 0.1f)
blueState = HandState.Returning;
break;
case HandState.Returning:
// 将手臂移动到原点
blueHand.position = Vector3.MoveTowards(blueHand.position, blueOrigin.position, returnSpeed * Time.deltaTime);
// 把抓取物体移动到手臂位置
if (blueGrabbed != null)
blueGrabbed.transform.position = blueHand.position;
// 到达原点时射击结束
if (Vector3.Distance(blueHand.position, blueOrigin.position) < 0.05f)
ResetBlue();
break;
}
}
// 重置蓝色手臂
void ResetBlue()
{
blueHand.position = blueOrigin.position;
blueHand.rotation = blueOrigin.rotation;
blueGrabbed = null;
blueState = HandState.Idle;
}
// 啟動紅色手臂
void ShootRed()
{
if (cam == null) return;
redGrabbed = null;
// 射击点对齐
Ray ray = cam.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
RaycastHit hit;
// Raycast距离
if (Physics.Raycast(ray, out hit, shootDistance))
{
redTarget = hit.point;
// 检测是哪个物体
if (hit.collider.CompareTag("Grabbable"))
redGrabbed = hit.collider.gameObject;
}
else
{
redTarget = ray.origin + ray.direction * shootDistance;
}
redState = HandState.Shooting;
}
// 处理红色手臂
void HandleRed()
{
switch (redState)
{
case HandState.Shooting:
// 把手臂移动到目标点
redHand.position = Vector3.MoveTowards(redHand.position, redTarget, speed * Time.deltaTime);
// 到达目标点时射击结束
if (Vector3.Distance(redHand.position, redTarget) < 0.1f)
redState = HandState.Returning;
break;
case HandState.Returning:
// 将手臂移动到原点
redHand.position = Vector3.MoveTowards(redHand.position, redOrigin.position, returnSpeed * Time.deltaTime);
// 把抓取物体移动到手臂位置
if (redGrabbed != null)
redGrabbed.transform.position = redHand.position;
// 到达原点时射击结束
if (Vector3.Distance(redHand.position, redOrigin.position) < 0.05f)
ResetRed();
break;
}
}
// 重置红色手臂
void ResetRed()
{
redHand.position = redOrigin.position;
redHand.rotation = redOrigin.rotation;
redGrabbed = null;
redState = HandState.Idle;
}
// 更新枪位置
void UpdateGunRotation()
{
// BLUE
blueGun.localPosition = blueGunStartLocalPos;
if (blueState == HandState.Shooting)
{
// 计算手臂和枪之间的方向
Vector3 dir = blueHand.position - blueGun.position;
if (dir != Vector3.zero)
{
Quaternion lookRot = Quaternion.LookRotation(dir);
// 修复纵向90度
blueGun.rotation = lookRot * Quaternion.Euler(-90f, 0f, 0f);
}
}
// RED
redGun.localPosition = redGunStartLocalPos;
if (redState == HandState.Shooting)
{
// 计算手臂和枪之间的方向
Vector3 dir = redHand.position - redGun.position;
if (dir != Vector3.zero)
{
Quaternion lookRot = Quaternion.LookRotation(dir);
// 修复纵向90度
redGun.rotation = lookRot * Quaternion.Euler(-90f, 0f, 0f);
}
}
}
// 更新线条
void UpdateLines()
{
if (blueLine != null)
{
if (blueState != HandState.Idle)
{
blueLine.enabled = true;
blueLine.SetPosition(0, blueShootPoint.position);
blueLine.SetPosition(1, blueHand.position);
}
else
blueLine.enabled = false;
}
if (redLine != null)
{
if (redState != HandState.Idle)
{
redLine.enabled = true;
redLine.SetPosition(0, redShootPoint.position);
redLine.SetPosition(1, redHand.position);
}
else
redLine.enabled = false;
}
}
}
评论 (0)