refactor: 重新规划了项目结构
删除了冗余的控制类
This commit is contained in:
180
Assets/Behaviours/BallStickBehaviour.cs
Normal file
180
Assets/Behaviours/BallStickBehaviour.cs
Normal file
@@ -0,0 +1,180 @@
|
||||
using System.Collections.Generic;
|
||||
using Models;
|
||||
using UnityEngine;
|
||||
using Utils.PoseTransformHandlers;
|
||||
|
||||
public class MainBehaviour : MonoBehaviour
|
||||
{
|
||||
private readonly GameObject[] _nodes = new GameObject[PoseLandmarkType.MaxValue];
|
||||
private readonly List<Bond> _bonds = new List<Bond>();
|
||||
private readonly PoseTransform[] _poseTransforms = new PoseTransform[PoseLandmarkType.MaxValue];
|
||||
private readonly UdpListener _listener = new UdpListener();
|
||||
private const float Scale = 0.2f;
|
||||
|
||||
// Start is called before the first frame update
|
||||
private void Start()
|
||||
{
|
||||
PoseTransform.AverageLength = 3;
|
||||
|
||||
CreateNodes();
|
||||
CreateBonds();
|
||||
|
||||
_listener.AddHandler(OnReceive);
|
||||
_listener.Connect(5000);
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
private void Update()
|
||||
{
|
||||
for (var i = 0; i < PoseLandmarkType.MaxValue; i++)
|
||||
{
|
||||
_nodes[i].transform.position = _poseTransforms[i].ResultPosition * -5;
|
||||
}
|
||||
|
||||
foreach (var bond in _bonds)
|
||||
{
|
||||
bond.UpdateBond();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
_listener.DisConnect();
|
||||
}
|
||||
|
||||
private void OnReceive(List<PoseLandmark> landmarks)
|
||||
{
|
||||
foreach (var landmark in landmarks)
|
||||
{
|
||||
PoseTransform.UpdatePosition(ref _poseTransforms[landmark.Type.Value], landmark);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateNodes()
|
||||
{
|
||||
for (var i = 0; i < PoseLandmarkType.MaxValue; i++)
|
||||
{
|
||||
var ball = GameObject.CreatePrimitive(PrimitiveType.Sphere);
|
||||
|
||||
ball.transform.localScale = new Vector3(Scale, Scale, Scale);
|
||||
|
||||
if (i <= 10)
|
||||
{
|
||||
ball.GetComponent<Renderer>().material.color = Color.red;//给头部添加颜色
|
||||
}
|
||||
else if (i <= 22)
|
||||
{
|
||||
ball.GetComponent<Renderer>().material.color = Color.blue;//给手部添加颜色
|
||||
}
|
||||
else if (i <= 32)
|
||||
{
|
||||
ball.GetComponent<Renderer>().material.color = Color.green;//给脚部添加颜色
|
||||
}
|
||||
|
||||
_nodes[i] = ball;
|
||||
_poseTransforms[i] = new PoseTransform(i, new AverageHandler());
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateBonds()
|
||||
{
|
||||
var headBonds = new[]
|
||||
{
|
||||
PoseLandmarkType.RightEar,
|
||||
PoseLandmarkType.RightEyeOuter,
|
||||
PoseLandmarkType.RightEye,
|
||||
PoseLandmarkType.RightEyeInner,
|
||||
PoseLandmarkType.Nose,
|
||||
PoseLandmarkType.LeftEyeInner,
|
||||
PoseLandmarkType.LeftEye,
|
||||
PoseLandmarkType.LeftEyeOuter,
|
||||
PoseLandmarkType.LeftEar
|
||||
};
|
||||
_bonds.AddRange(GenerateBondsList(headBonds));
|
||||
|
||||
var monthBonds = new[]
|
||||
{
|
||||
PoseLandmarkType.MouthLeft,
|
||||
PoseLandmarkType.MouthRight,
|
||||
};
|
||||
_bonds.AddRange(GenerateBondsList(monthBonds));
|
||||
|
||||
var leftArmBonds = new[]
|
||||
{
|
||||
PoseLandmarkType.LeftShoulder,
|
||||
PoseLandmarkType.LeftElbow,
|
||||
PoseLandmarkType.LeftWrist,
|
||||
PoseLandmarkType.LeftPinky,
|
||||
PoseLandmarkType.LeftIndex,
|
||||
PoseLandmarkType.LeftWrist,
|
||||
PoseLandmarkType.LeftThumb
|
||||
};
|
||||
_bonds.AddRange(GenerateBondsList(leftArmBonds));
|
||||
|
||||
var rightArmBonds = new[]
|
||||
{
|
||||
PoseLandmarkType.RightShoulder,
|
||||
PoseLandmarkType.RightElbow,
|
||||
PoseLandmarkType.RightWrist,
|
||||
PoseLandmarkType.RightPinky,
|
||||
PoseLandmarkType.RightIndex,
|
||||
PoseLandmarkType.RightWrist,
|
||||
PoseLandmarkType.RightThumb
|
||||
};
|
||||
_bonds.AddRange(GenerateBondsList(rightArmBonds));
|
||||
|
||||
var leftLegBonds = new[]
|
||||
{
|
||||
PoseLandmarkType.LeftShoulder,
|
||||
PoseLandmarkType.LeftHip,
|
||||
PoseLandmarkType.LeftKnee,
|
||||
PoseLandmarkType.LeftAnkle,
|
||||
PoseLandmarkType.LeftHeel,
|
||||
PoseLandmarkType.LeftFootIndex,
|
||||
PoseLandmarkType.LeftAnkle
|
||||
};
|
||||
_bonds.AddRange(GenerateBondsList(leftLegBonds));
|
||||
|
||||
var rightLegBonds = new[]
|
||||
{
|
||||
PoseLandmarkType.RightShoulder,
|
||||
PoseLandmarkType.RightHip,
|
||||
PoseLandmarkType.RightKnee,
|
||||
PoseLandmarkType.RightAnkle,
|
||||
PoseLandmarkType.RightHeel,
|
||||
PoseLandmarkType.RightFootIndex,
|
||||
PoseLandmarkType.RightAnkle
|
||||
};
|
||||
_bonds.AddRange(GenerateBondsList(rightLegBonds));
|
||||
|
||||
// 最后手动添加身体上的两条横线
|
||||
_bonds.Add(new Bond(
|
||||
_nodes[PoseLandmarkType.LeftShoulder],
|
||||
_nodes[PoseLandmarkType.RightShoulder],
|
||||
Scale));
|
||||
_bonds.Add(new Bond(
|
||||
_nodes[PoseLandmarkType.LeftHip],
|
||||
_nodes[PoseLandmarkType.RightHip],
|
||||
Scale));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建棍子列表
|
||||
/// </summary>
|
||||
/// <param name="nodes">需要连接起来的关键点 需要按顺序设置</param>
|
||||
/// <returns></returns>
|
||||
private List<Bond> GenerateBondsList(int[] nodes)
|
||||
{
|
||||
var bonds = new List<Bond>();
|
||||
|
||||
for (var i = 0; i < nodes.Length - 1; i++)
|
||||
{
|
||||
bonds.Add(new Bond(
|
||||
_nodes[nodes[i]],
|
||||
_nodes[nodes[i + 1]],
|
||||
Scale));
|
||||
}
|
||||
|
||||
return bonds;
|
||||
}
|
||||
}
|
11
Assets/Behaviours/BallStickBehaviour.cs.meta
Normal file
11
Assets/Behaviours/BallStickBehaviour.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 574a3724e040787f7afd9341fba89cf2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
146
Assets/Behaviours/CameraBehaviour.cs
Normal file
146
Assets/Behaviours/CameraBehaviour.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class CameraBehaviour : MonoBehaviour
|
||||
{
|
||||
public Transform target;
|
||||
|
||||
private const int MouseWheelSensitivity = 1; //滚轮灵敏度设置
|
||||
private const int MouseZoomMin = 1; //相机距离最小值
|
||||
private const int MouseZoomMax = 20; //相机距离最大值
|
||||
private const float XSpeed = 250.0f;
|
||||
private const float YSpeed = 120.0f;
|
||||
private const int YMinLimit = -360;
|
||||
private const int YMaxLimit = 360;
|
||||
|
||||
private float _eulerX; //存储相机的euler角
|
||||
private float _eulerY; //存储相机的euler角
|
||||
|
||||
private float _distance = 5; //相机和target之间的距离,因为相机的Z轴总是指向target,也就是相机z轴方向上的距离
|
||||
private Vector3 _targetOnScreenPosition; //目标的屏幕坐标,第三个值为z轴距离
|
||||
private Quaternion _cameraRotation; //存储相机的姿态四元数
|
||||
private Vector3 _targetPosition; //target的位置
|
||||
private Vector3 _initPosition; //平移时用于存储平移的起点位置
|
||||
private Vector3 _cameraX; //相机的x轴方向向量
|
||||
private Vector3 _cameraY; //相机的y轴方向向量
|
||||
private Vector3 _initScreenPosition; //中键刚按下时鼠标的屏幕坐标(第三个值其实没什么用)
|
||||
private Vector3 _cursorScreenPosition; //当前鼠标的屏幕坐标(第三个值其实没什么用)
|
||||
|
||||
private Camera _mainCamera;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
//这里就是设置一下初始的相机视角以及一些其他变量,这里的x和y。。。是和下面getAxis的mouse x与mouse y对应
|
||||
var angles = transform.eulerAngles;
|
||||
_eulerX = angles.y;
|
||||
_eulerY = angles.x;
|
||||
_targetPosition = target.position;
|
||||
//_cameraRotation = Quaternion.Euler(_eulerY + 60, _eulerX, 0);
|
||||
_cameraRotation = Quaternion.Euler(_eulerY, _eulerX, 0);
|
||||
// 引入中间变量 提高代码效率
|
||||
var transform1 = transform;
|
||||
//设置相机姿态
|
||||
transform1.rotation = _cameraRotation;
|
||||
//设置相机位置
|
||||
transform1.position = _cameraRotation * new Vector3(0, 0, -_distance) + _targetPosition;
|
||||
|
||||
// 获得主摄像机
|
||||
_mainCamera = Camera.main;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
//鼠标右键旋转功能
|
||||
if (Input.GetMouseButton(1))
|
||||
{
|
||||
_eulerX += Input.GetAxis("Mouse X") * XSpeed * 0.02f;
|
||||
_eulerY -= Input.GetAxis("Mouse Y") * YSpeed * 0.02f;
|
||||
|
||||
_eulerY = ClampAngle(_eulerY, YMinLimit, YMaxLimit);
|
||||
|
||||
//_cameraRotation = Quaternion.Euler(_eulerY + 60, _eulerX, 0);
|
||||
_cameraRotation = Quaternion.Euler(_eulerY, _eulerX, 0);
|
||||
var position = _cameraRotation * new Vector3(0.0f, 0.0f, -_distance) + _targetPosition;
|
||||
|
||||
// 引入中间变量 提高代码效率
|
||||
var transform1 = transform;
|
||||
transform1.rotation = _cameraRotation;
|
||||
transform1.position = position;
|
||||
}
|
||||
else if (Input.GetAxis("Mouse ScrollWheel") != 0) //鼠标滚轮缩放功能
|
||||
{
|
||||
if (_distance is >= MouseZoomMin and <= MouseZoomMax)
|
||||
{
|
||||
_distance -= Input.GetAxis("Mouse ScrollWheel") * MouseWheelSensitivity;
|
||||
}
|
||||
|
||||
if (_distance < MouseZoomMin)
|
||||
{
|
||||
_distance = MouseZoomMin;
|
||||
}
|
||||
|
||||
if (_distance > MouseZoomMax)
|
||||
{
|
||||
_distance = MouseZoomMax;
|
||||
}
|
||||
|
||||
transform.position = _cameraRotation * new Vector3(0.0F, 0.0F, -_distance) + _targetPosition;
|
||||
}
|
||||
|
||||
//鼠标中键平移
|
||||
if (Input.GetMouseButtonDown(2))
|
||||
{
|
||||
// 添加中间变量
|
||||
// 提高代码效率
|
||||
var transform1 = transform;
|
||||
_cameraX = transform1.right;
|
||||
_cameraY = transform1.up;
|
||||
|
||||
_initScreenPosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, _targetOnScreenPosition.z);
|
||||
|
||||
//targetOnScreenPosition.z为目标物体到相机平面的法线距离
|
||||
_targetOnScreenPosition = _mainCamera.WorldToScreenPoint(_targetPosition);
|
||||
_initPosition = _targetPosition;
|
||||
}
|
||||
|
||||
if (Input.GetMouseButton(2))
|
||||
{
|
||||
_cursorScreenPosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, _targetOnScreenPosition.z);
|
||||
//0.01这个系数是控制平移的速度,要根据相机和目标物体的distance来灵活选择
|
||||
target.position = _initPosition - 0.01f * ((_cursorScreenPosition.x - _initScreenPosition.x) * _cameraX +
|
||||
(_cursorScreenPosition.y - _initScreenPosition.y) * _cameraY);
|
||||
|
||||
//重新计算位置
|
||||
var mPosition = _cameraRotation * new Vector3(0.0F, 0.0F, -_distance) + target.position;
|
||||
transform.position = mPosition;
|
||||
|
||||
// //用这个会让相机的平移变得更平滑,但是可能在你ButtonUp时未使相机移动到应到的位置,导致再进行旋转与缩放操作时出现短暂抖动
|
||||
//transform.position=Vector3.Lerp(transform.position,mPosition,Time.deltaTime*moveSpeed);
|
||||
}
|
||||
|
||||
if (Input.GetMouseButtonUp(2))
|
||||
{
|
||||
//平移结束把cameraTargetPosition的位置更新一下,不然会影响缩放与旋转功能
|
||||
_targetPosition = target.position;
|
||||
}
|
||||
}
|
||||
|
||||
//将angle限制在min~max之间
|
||||
private static float ClampAngle(float angle, float min, float max)
|
||||
{
|
||||
if (angle < -360)
|
||||
angle += 360;
|
||||
if (angle > 360)
|
||||
angle -= 360;
|
||||
return Mathf.Clamp(angle, min, max);
|
||||
}
|
||||
|
||||
/*void testScreenToWorldPoint()
|
||||
{
|
||||
//第三个坐标指的是在相机z轴指向方向上的距离
|
||||
Vector3 screenPoint = Camera.main.WorldToScreenPoint(_targetPosition);
|
||||
Debug.Log("ScreenPoint: " + screenPoint);
|
||||
|
||||
// var worldPosition = Camera.main.ScreenToWorldPoint(new Vector3(1,1,10));
|
||||
// Debug.Log("worldPosition: "+worldPosition);
|
||||
}*/
|
||||
}
|
11
Assets/Behaviours/CameraBehaviour.cs.meta
Normal file
11
Assets/Behaviours/CameraBehaviour.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9189b565e8ba9bfc3bdaa38149e3e13f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user