You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
432 lines
12 KiB
432 lines
12 KiB
4 years ago
|
/*
|
||
|
* 程序功能:
|
||
|
* 设置手臂的行为 action
|
||
|
* 设置手臂的帧序列 frameIndex
|
||
|
*/
|
||
|
using System;
|
||
|
using UnityEngine;
|
||
|
/// <summary>
|
||
|
/// 手臂动作帧
|
||
|
/// </summary>
|
||
|
public class ArmActionFrame : MonoBehaviour
|
||
|
{
|
||
|
//动作类型
|
||
|
public ActionType action = ActionType.RotateToTarget;
|
||
|
//序列
|
||
|
public int FrameIndex;
|
||
|
//动作完成
|
||
|
public Action OnFinished;
|
||
|
//模型轴向错误
|
||
|
public bool IsOpposite = false;
|
||
|
//手臂长度偏移量
|
||
|
public int ArmLenthOffset = 16;
|
||
|
//x轴旋转的最大角度
|
||
|
public float MaxRotateX = 0;
|
||
|
public float MinRotateX = -84f;
|
||
|
//臂长
|
||
|
public float Maxlength = 15.8f;
|
||
|
public float Minlength = 0.01634139f;
|
||
|
//动作是否完成
|
||
|
private bool IsFinished = true;
|
||
|
//动作速度
|
||
|
public float Speed = 20;
|
||
|
//目标点
|
||
|
private Vector3 targetPosition;
|
||
|
//旋转的向量
|
||
|
private Vector3 newDir;
|
||
|
//旋转量
|
||
|
private Quaternion quaternion;
|
||
|
//根据距离旋转高度
|
||
|
public int Distance = 20;
|
||
|
#region 移动的变量
|
||
|
//当前高度
|
||
|
private ArmAction manager;
|
||
|
private void Awake()
|
||
|
{
|
||
|
manager = GetComponentInParent<ArmAction>();
|
||
|
}
|
||
|
public float CurrentHeight
|
||
|
{
|
||
|
set
|
||
|
{
|
||
|
if (value >= Maxlength)
|
||
|
{
|
||
|
value = Maxlength;
|
||
|
Finished();
|
||
|
}
|
||
|
if (value <= Minlength)
|
||
|
{
|
||
|
value = Minlength;
|
||
|
Finished();
|
||
|
}
|
||
|
transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y, value);
|
||
|
#if UNITY_EDITOR
|
||
|
Debug.DrawLine(manager.EndTrans.position, targetPosition, Color.yellow);
|
||
|
#endif
|
||
|
}
|
||
|
get { return transform.localPosition.z; }
|
||
|
}
|
||
|
#endregion
|
||
|
/// <summary>
|
||
|
/// 根据坐标行动作
|
||
|
/// </summary>
|
||
|
/// <param name="position">坐标</param>
|
||
|
public void Init(Vector3 position, bool isRest)
|
||
|
{
|
||
|
//停止当前动作
|
||
|
Stop();
|
||
|
//设置目标点,初始化信息
|
||
|
targetPosition = position;
|
||
|
isRestPosition = isRest;
|
||
|
switch (action)
|
||
|
{
|
||
|
case ActionType.RotateToTarget:
|
||
|
InitAllDir();
|
||
|
break;
|
||
|
case ActionType.RotateToTargetVertacal:
|
||
|
InitVetacalDir();
|
||
|
break;
|
||
|
case ActionType.RotateToTargetHorizatal:
|
||
|
InitHorizatalDir();
|
||
|
break;
|
||
|
case ActionType.TranlateToForward:
|
||
|
InitTarnslateToForward();
|
||
|
break;
|
||
|
case ActionType.RotateVertacalWithDistance:
|
||
|
InitVetacalDistance();
|
||
|
break;
|
||
|
}
|
||
|
//动作开始
|
||
|
IsFinished = false;
|
||
|
}
|
||
|
|
||
|
private Vector3 resetPosition;
|
||
|
private Quaternion resetRotation;
|
||
|
private bool isRestPosition = false;
|
||
|
private void Start()
|
||
|
{
|
||
|
//记录初始臂长
|
||
|
//resetPosition = transform.position;
|
||
|
//记录初始水平角度
|
||
|
resetRotation = transform.localRotation;
|
||
|
}
|
||
|
public void Play(Vector3 position)
|
||
|
{
|
||
|
Init(position, false);
|
||
|
}
|
||
|
public void Play()
|
||
|
{
|
||
|
Init(manager.targetPosition, false);
|
||
|
}
|
||
|
/// <summary>
|
||
|
/// 复位
|
||
|
/// </summary>
|
||
|
public void ResetArm()
|
||
|
{
|
||
|
Init(Vector3.zero, true);
|
||
|
}
|
||
|
/// <summary>
|
||
|
/// 停止动作
|
||
|
/// </summary>
|
||
|
public void Stop()
|
||
|
{
|
||
|
IsFinished = true;
|
||
|
}
|
||
|
/// <summary>
|
||
|
/// 动作完成,执行下一个动作
|
||
|
/// </summary>
|
||
|
public void Finished()
|
||
|
{
|
||
|
Stop();
|
||
|
if (OnFinished != null)
|
||
|
{
|
||
|
OnFinished();
|
||
|
}
|
||
|
}
|
||
|
/// <summary>
|
||
|
/// 帧更新
|
||
|
/// </summary>
|
||
|
void Update()
|
||
|
{
|
||
|
if (!IsFinished)
|
||
|
{
|
||
|
Move();
|
||
|
}
|
||
|
}
|
||
|
/// <summary>
|
||
|
///
|
||
|
/// </summary>
|
||
|
private void Move()
|
||
|
{
|
||
|
if (action == ActionType.TranlateToForward)
|
||
|
{
|
||
|
//臂长
|
||
|
float d2E = Mathf.FloorToInt(Vector3.Distance(manager.EndTrans.position, manager.StartTrans.position)) + ArmLenthOffset;
|
||
|
float d2T = Mathf.FloorToInt(Vector3.Distance(manager.StartTrans.position, targetPosition));//臂底端到目标的距离
|
||
|
if (d2E < d2T)
|
||
|
{
|
||
|
CurrentHeight += Time.deltaTime * Speed;
|
||
|
}
|
||
|
else if (d2E > d2T)
|
||
|
{
|
||
|
CurrentHeight -= Time.deltaTime * Speed;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Finished();
|
||
|
}
|
||
|
}
|
||
|
else if (action == ActionType.RotateVertacalWithDistance)
|
||
|
{
|
||
|
//复位
|
||
|
if (isRestPosition)
|
||
|
{
|
||
|
transform.localRotation = Quaternion.RotateTowards(transform.localRotation, quaternion, Time.deltaTime * Speed * 2);
|
||
|
if (transform.localRotation == quaternion)
|
||
|
{
|
||
|
Finished();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//检查尾端与目标点距离
|
||
|
float distance = Mathf.Round(Vector3.Distance(manager.EndTrans.position, targetPosition));
|
||
|
float targetDistance = ArmLenthOffset + Distance;
|
||
|
|
||
|
//Debug.Log(string.Format("距离:{0}-目标距离:{1}", distance, targetDistance));
|
||
|
//距离小的时候抬高
|
||
|
if (distance < targetDistance)
|
||
|
{
|
||
|
Raise(Time.deltaTime * Speed * 2);
|
||
|
//Debug.Log("需要抬高");
|
||
|
}
|
||
|
else if (distance > targetDistance)
|
||
|
{
|
||
|
Decline(Time.deltaTime * Speed * 2);
|
||
|
//Debug.Log("需要降低");
|
||
|
}
|
||
|
float x = CheckValue(transform.localEulerAngles.x);
|
||
|
if (distance == targetDistance || x == MinRotateX || x == MaxRotateX)
|
||
|
{
|
||
|
Finished();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//复位
|
||
|
if (isRestPosition)
|
||
|
{
|
||
|
transform.localRotation = Quaternion.RotateTowards(transform.localRotation, quaternion, Time.deltaTime * Speed * 2);
|
||
|
if (transform.localRotation == quaternion)
|
||
|
{
|
||
|
Finished();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
transform.rotation = Quaternion.RotateTowards(transform.rotation, quaternion, Time.deltaTime * Speed * 2);
|
||
|
float x = CheckValue(transform.localEulerAngles.x);
|
||
|
if (x < MinRotateX && !IsOpposite)
|
||
|
{
|
||
|
transform.localEulerAngles = new Vector3(MinRotateX, transform.localEulerAngles.y, transform.localEulerAngles.z);
|
||
|
Finished();
|
||
|
return;
|
||
|
}
|
||
|
if (x > MaxRotateX & !IsOpposite)
|
||
|
{
|
||
|
transform.localEulerAngles = new Vector3(MaxRotateX, transform.localEulerAngles.y, transform.localEulerAngles.z);
|
||
|
Finished();
|
||
|
return;
|
||
|
}
|
||
|
if (transform.rotation == quaternion)
|
||
|
{
|
||
|
|
||
|
Finished();
|
||
|
}
|
||
|
}
|
||
|
//Debug
|
||
|
#if UNITY_EDITOR
|
||
|
switch (action)
|
||
|
{
|
||
|
case ActionType.RotateToTarget:
|
||
|
Debug.DrawRay(transform.position, newDir, Color.blue);
|
||
|
break;
|
||
|
case ActionType.RotateToTargetVertacal:
|
||
|
Debug.DrawRay(transform.position, newDir, Color.green);
|
||
|
break;
|
||
|
case ActionType.RotateToTargetHorizatal:
|
||
|
Debug.DrawRay(transform.position, newDir, Color.red);
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
/// <summary>
|
||
|
/// 向下降低Bi1
|
||
|
/// </summary>
|
||
|
/// <param name="speed"></param>
|
||
|
public void Decline(float speed)
|
||
|
{
|
||
|
float x = transform.localEulerAngles.x;
|
||
|
float y = transform.localEulerAngles.y;
|
||
|
x = CheckValue(x);
|
||
|
x += speed;
|
||
|
x = Mathf.Clamp(x, MinRotateX, MaxRotateX);//模型穿插,调整模型预设后,这里参数也跟着修改。
|
||
|
transform.localEulerAngles = new Vector3(x, y, 0);
|
||
|
}
|
||
|
/// <summary>
|
||
|
/// 向上抬起Bi1
|
||
|
/// </summary>
|
||
|
/// <param name="speed"></param>
|
||
|
public void Raise(float speed)
|
||
|
{
|
||
|
float x = transform.localEulerAngles.x;
|
||
|
float y = transform.localEulerAngles.y;
|
||
|
x = CheckValue(x);
|
||
|
x -= speed;
|
||
|
x = Mathf.Clamp(x, MinRotateX, MaxRotateX);//模型穿插,调整模型预设后,这里参数也跟着修改。
|
||
|
transform.localEulerAngles = new Vector3(x, y, 0);
|
||
|
}
|
||
|
/// <summary>
|
||
|
/// 初始化所有方位的旋转量
|
||
|
/// </summary>
|
||
|
private void InitAllDir()
|
||
|
{
|
||
|
if (isRestPosition)
|
||
|
{
|
||
|
quaternion = resetRotation;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
var targetDir = targetPosition - transform.position;
|
||
|
var forward = transform.forward;
|
||
|
newDir = targetDir;
|
||
|
quaternion = Quaternion.LookRotation(newDir);
|
||
|
}
|
||
|
}
|
||
|
/// <summary>
|
||
|
/// 初始化垂直方向旋转量
|
||
|
/// </summary>
|
||
|
private void InitVetacalDir()
|
||
|
{
|
||
|
|
||
|
if (isRestPosition)
|
||
|
{
|
||
|
quaternion = resetRotation;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Vector3 hightOffSetPosition = new Vector3(targetPosition.x, targetPosition.y, targetPosition.z);
|
||
|
Vector3 targetDir = hightOffSetPosition - transform.position;
|
||
|
newDir = targetDir - Vector3.Dot(targetDir, transform.right) * transform.right;
|
||
|
if (IsOpposite)
|
||
|
{
|
||
|
float temp = Vector3.Angle(newDir, transform.forward);
|
||
|
if (temp > 90f)
|
||
|
{
|
||
|
quaternion = Quaternion.LookRotation(-newDir, transform.up);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
quaternion = Quaternion.LookRotation(-newDir, -transform.up);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
quaternion = Quaternion.LookRotation(newDir, transform.up);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
public void InitVetacalDistance()
|
||
|
{
|
||
|
if (isRestPosition)
|
||
|
{
|
||
|
quaternion = resetRotation;
|
||
|
}
|
||
|
}
|
||
|
/// <summary>
|
||
|
/// 初始化水平方向旋转量
|
||
|
/// </summary>
|
||
|
private void InitHorizatalDir()
|
||
|
{
|
||
|
if (isRestPosition)
|
||
|
{
|
||
|
quaternion = resetRotation;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// 底臂part1到目标位置的向量
|
||
|
Vector3 targetDir = targetPosition - transform.position;
|
||
|
//【BiTar在底臂forward方向上的分向量】 = 【BiTar向量】 - 【BiTar在底臂up方向上的分向量】
|
||
|
newDir = targetDir - Vector3.Dot(targetDir, transform.up) * transform.up;
|
||
|
//由BiTar的【forward分向量】和【up分向量组成的】 旋转量Quaternion
|
||
|
if (IsOpposite)
|
||
|
{
|
||
|
float temp = Vector3.Angle(newDir, transform.forward);
|
||
|
if (temp > 90f)
|
||
|
{
|
||
|
quaternion = Quaternion.LookRotation(-newDir, transform.up);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
quaternion = Quaternion.LookRotation(-newDir, -transform.up);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
quaternion = Quaternion.LookRotation(newDir, transform.up);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
/// <summary>
|
||
|
/// 初始化移动信息
|
||
|
/// </summary>
|
||
|
private void InitTarnslateToForward()
|
||
|
{
|
||
|
if (isRestPosition)
|
||
|
{
|
||
|
targetPosition = transform.position;
|
||
|
}
|
||
|
}
|
||
|
/// <summary>
|
||
|
/// 验证旋转角度
|
||
|
/// </summary>
|
||
|
/// <param name="x"></param>
|
||
|
/// <returns></returns>
|
||
|
protected float CheckValue(float x)
|
||
|
{
|
||
|
if (x >= 180 && x <= 360)
|
||
|
{
|
||
|
x = x - 360;
|
||
|
}
|
||
|
return x;
|
||
|
}
|
||
|
}
|
||
|
/// <summary>
|
||
|
/// 动作类型
|
||
|
/// </summary>
|
||
|
public enum ActionType
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// 朝向举臂
|
||
|
/// </summary>
|
||
|
RotateToTarget,
|
||
|
/// <summary>
|
||
|
/// 垂直举臂
|
||
|
/// </summary>
|
||
|
RotateToTargetVertacal,
|
||
|
/// <summary>
|
||
|
/// 水平举臂
|
||
|
/// </summary>
|
||
|
RotateToTargetHorizatal,
|
||
|
/// <summary>
|
||
|
/// 伸缩举臂
|
||
|
/// </summary>
|
||
|
TranlateToForward,
|
||
|
/// <summary>
|
||
|
/// 根据距离旋转高度
|
||
|
/// </summary>
|
||
|
RotateVertacalWithDistance
|
||
|
}
|