using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
///
/// 行吊控制器
/// 基于标准父级移动轴
///
///
public class HangDiaoController : MonoBehaviour
{
public static HangDiaoController instance;
public enum HangDiaoRunningState
{
待机,
横梁移动,
电机移动,
展开吊钩,
收起吊钩,
自由追随
}
public class HangDiaoRunningStateEventData
{
public HangDiaoRunningState runningState;
public bool finished;
public HangDiaoRunningStateEventData(HangDiaoRunningState state, bool finished)
{
this.runningState = state;
this.finished = finished;
}
}
//行吊运行状态
public delegate void HD_RuningEvent(HangDiaoRunningStateEventData eventData);
//行吊完成状态
public HD_RuningEvent RuningStateChanged;
public HangDiaoRunningState hangDiaoRuningState = HangDiaoRunningState.待机;
//追随目标
public Transform targetPoint;
//行吊横梁
public Transform hd_HengLiang;
//行吊横梁电机
public Transform hd_HengXiangDianJi;
public Transform hd_ShengZi_Chang;
public Transform hd_ShengZi_Duan;
//挂钩
public Transform hd_GuaGou;
//实际挂钩点距挂钩模型的偏移量
public Vector3 guaGouOffset = new Vector3(0, -0.0022f, -0.1745f);
//绳子的缩放比例 1 :1.137115
public float shengZiDuan_Scale = 1.37115f;
public float shengZiChang_Scale = 1.49664f;
//挂钩初始高度(距电机的相对Z轴)
private float guaGouInitHeight = -0.5f;
//横梁移动速度
public float hengLiangMoveSpeed = 1f;
//吊钩移动速度
public float diaoGouMoveSpeed = 0.5f;
//横梁电机移动速度
public float hengLiangDianJiMoveSpeed = 1f;
//根据时间调整移动速度
public float moveTimeLimit = 2;
private bool moveToTarget = false;
public void Awake()
{
instance = this;
}
// Update is called once per frame
void Update()
{
CheckRuningState();
}
///
/// 运行状态检测
///
public void CheckRuningState()
{
switch (hangDiaoRuningState)
{
case HangDiaoRunningState.待机:
break;
case HangDiaoRunningState.横梁移动:
HD_HengLiang_Move();
break;
case HangDiaoRunningState.电机移动:
HD_HengLiangDianJi_Move();
break;
case HangDiaoRunningState.展开吊钩:
HD_DiaoGou_Open();
break;
case HangDiaoRunningState.收起吊钩:
HD_DiaoGou_ShouHui();
break;
case HangDiaoRunningState.自由追随:
UpdataByTagetPoint();
break;
default:
break;
}
}
///
/// 更新行吊状态至目标位置
///
///
public void SetTargetPos(Vector3 pos)
{
Vector3 targetPointLocalPosInHangDiao = this.transform.InverseTransformPoint(pos);
//行吊位置更新
hd_HengLiang.transform.localPosition = new Vector3(hd_HengLiang.localPosition.x, hd_HengLiang.localPosition.y, targetPointLocalPosInHangDiao.z);
//电机位置更新
Vector3 targetPointLocalPosInHengLiang = hd_HengLiang.InverseTransformPoint(pos);
hd_HengXiangDianJi.localPosition = new Vector3(targetPointLocalPosInHengLiang.x, hd_HengXiangDianJi.localPosition.y, hd_HengXiangDianJi.localPosition.z);
//更新挂钩位置
hd_GuaGou.position = pos - hd_GuaGou.TransformVector(guaGouOffset);
//更新绳索缩放
hd_ShengZi_Chang.localScale = new Vector3(1,1,hd_GuaGou.InverseTransformPoint(hd_ShengZi_Chang.position).z / shengZiChang_Scale);
hd_ShengZi_Duan.localScale = new Vector3(1,1, hd_GuaGou.InverseTransformPoint(hd_ShengZi_Duan.position).z / shengZiDuan_Scale);
}
///
/// 移动到目标位置
///
public void MoveToTargetPoint()
{
if (!moveToTarget)
{
RuningStateChanged += MoveToTargetRuningStateChanged;
}
moveToTarget = true;
hangDiaoRuningState = HangDiaoRunningState.收起吊钩;
}
///
/// 在时间范围内移动至目标位置
///
public void MoveToTargetPointInTime()
{
CheckTimeChangedSpeed(moveTimeLimit);
MoveToTargetPoint();
}
///
/// 设置目标位置
///
///
public void SetTarget(Transform t)
{
targetPoint = t;
hangDiaoRuningState = HangDiaoRunningState.待机;
}
public void MoveToTargetRuningStateChanged(HangDiaoRunningStateEventData eventData)
{
if (!eventData.finished) return;
//Debug.Log(hangDiaoRuningState.ToString() + "Finished");
switch (eventData.runningState)
{
case HangDiaoRunningState.横梁移动:
hangDiaoRuningState = HangDiaoRunningState.电机移动;
break;
case HangDiaoRunningState.电机移动:
hangDiaoRuningState = HangDiaoRunningState.展开吊钩;
break;
case HangDiaoRunningState.展开吊钩:
hangDiaoRuningState = HangDiaoRunningState.自由追随;
RuningStateChanged -= MoveToTargetRuningStateChanged;
moveToTarget = false;
break;
case HangDiaoRunningState.收起吊钩:
hangDiaoRuningState = HangDiaoRunningState.横梁移动;
break;
}
}
#region 状态
///
/// 实时更新目标位置
///
public void UpdataByTagetPoint()
{
if (targetPoint == null) return;
Vector3 targetPointLocalPosInHangDiao = this.transform.InverseTransformPoint(targetPoint.position);
//行吊位置更新
hd_HengLiang.transform.localPosition = new Vector3(hd_HengLiang.localPosition.x, hd_HengLiang.localPosition.y, targetPointLocalPosInHangDiao.z);
//电机位置更新
Vector3 targetPointLocalPosInHengLiang = hd_HengLiang.InverseTransformPoint(targetPoint.position);
hd_HengXiangDianJi.localPosition = new Vector3(targetPointLocalPosInHengLiang.x, hd_HengXiangDianJi.localPosition.y, hd_HengXiangDianJi.localPosition.z);
//更新挂钩位置
hd_GuaGou.position = targetPoint.position - hd_GuaGou.TransformVector(guaGouOffset);
//更新绳索缩放
hd_ShengZi_Chang.localScale = new Vector3(1,1,hd_GuaGou.InverseTransformPoint(hd_ShengZi_Chang.position).z / shengZiChang_Scale);
hd_ShengZi_Duan.localScale = new Vector3(1,1,hd_GuaGou.InverseTransformPoint(hd_ShengZi_Duan.position).z / shengZiDuan_Scale);
}
///
/// 吊钩收回
///
public void HD_DiaoGou_ShouHui()
{
//更新挂钩位置
hd_GuaGou.localPosition =
new Vector3(hd_GuaGou.localPosition.x, hd_GuaGou.localPosition.y
, Mathf.MoveTowards(hd_GuaGou.localPosition.z, guaGouInitHeight, diaoGouMoveSpeed * Time.deltaTime));
hd_ShengZi_Chang.localScale = new Vector3(1, 1, hd_GuaGou.InverseTransformPoint(hd_ShengZi_Chang.position).y / shengZiChang_Scale);
hd_ShengZi_Duan.localScale = new Vector3(1,1,hd_GuaGou.InverseTransformPoint(hd_ShengZi_Duan.position).y / shengZiDuan_Scale);
if (hd_GuaGou.localPosition.z == guaGouInitHeight)
RuningStateChanged?.Invoke(new HangDiaoRunningStateEventData(HangDiaoRunningState.收起吊钩, true));
}
///
/// 吊钩拉伸
///
public void HD_DiaoGou_Open()
{
//更新挂钩位置
hd_GuaGou.localPosition =
new Vector3(hd_GuaGou.localPosition.x, hd_GuaGou.localPosition.y
, Mathf.MoveTowards(hd_GuaGou.localPosition.z,
(hd_HengXiangDianJi.InverseTransformPoint(targetPoint.position).z - guaGouOffset.z)
, diaoGouMoveSpeed * Time.deltaTime));
hd_ShengZi_Chang.localScale = new Vector3(1, 1, hd_GuaGou.InverseTransformPoint(hd_ShengZi_Chang.position).z / shengZiChang_Scale);
hd_ShengZi_Duan.localScale = new Vector3(1,1,hd_GuaGou.InverseTransformPoint(hd_ShengZi_Duan.position).z / shengZiDuan_Scale);
if (Mathf.Abs(hd_GuaGou.localPosition.z - (hd_HengXiangDianJi.InverseTransformPoint(targetPoint.position).z - guaGouOffset.z)) < 0.01f)
RuningStateChanged?.Invoke(new HangDiaoRunningStateEventData(HangDiaoRunningState.展开吊钩, true));
}
///
/// 行吊横梁移动
///
public void HD_HengLiang_Move()
{
Vector3 targetPointLocalPosInHangDiao = this.transform.InverseTransformPoint(targetPoint.position);
//行吊位置更新
hd_HengLiang.transform.localPosition = new Vector3(hd_HengLiang.localPosition.x, hd_HengLiang.localPosition.y
, Mathf.MoveTowards(hd_HengLiang.localPosition.z, targetPointLocalPosInHangDiao.z
, hengLiangMoveSpeed * Time.deltaTime));
if (hd_HengLiang.localPosition.z == targetPointLocalPosInHangDiao.z)
RuningStateChanged?.Invoke(new HangDiaoRunningStateEventData(HangDiaoRunningState.横梁移动, true));
}
///
/// 行吊横梁电机移动
///
public void HD_HengLiangDianJi_Move()
{
//电机位置更新
Vector3 targetPointLocalPosInHengLiang = hd_HengLiang.InverseTransformPoint(targetPoint.position);
hd_HengXiangDianJi.localPosition = new Vector3(Mathf.MoveTowards(hd_HengXiangDianJi.localPosition.x, targetPointLocalPosInHengLiang.x
, hengLiangMoveSpeed * Time.deltaTime), hd_HengXiangDianJi.localPosition.y, hd_HengXiangDianJi.localPosition.z);
if (hd_HengXiangDianJi.localPosition.x == targetPointLocalPosInHengLiang.x)
RuningStateChanged?.Invoke(new HangDiaoRunningStateEventData(HangDiaoRunningState.电机移动, true));
}
///
/// 根据整体时间改变速度
///
///
public void CheckTimeChangedSpeed(float moveMaxTime)
{
float targetMoveDistance = 0;
//吊钩回收
targetMoveDistance += Mathf.Abs(hd_GuaGou.localPosition.z - guaGouInitHeight);
//横梁移动
Vector3 targetPointLocalPosInHangDiao = this.transform.InverseTransformPoint(targetPoint.position);
targetMoveDistance += Mathf.Abs(hd_HengLiang.localPosition.z - targetPointLocalPosInHangDiao.z);
//电机移动
Vector3 targetPointLocalPosInHengLiang = hd_HengLiang.InverseTransformPoint(targetPoint.position);
targetMoveDistance += Mathf.Abs(hd_HengXiangDianJi.localPosition.x - targetPointLocalPosInHengLiang.x);
//吊车下放
targetMoveDistance += Mathf.Abs(guaGouInitHeight -
(hd_HengXiangDianJi.InverseTransformPoint(targetPoint.position).z - guaGouOffset.z));
float moveSpeed = targetMoveDistance / moveMaxTime;
diaoGouMoveSpeed = moveSpeed;
hengLiangMoveSpeed = moveSpeed;
hengLiangDianJiMoveSpeed = moveSpeed;
}
#endregion
}