在Unity中,物体的坐标分为局部坐标和世界坐标。
局部坐标是相对于物体的父对象的坐标系,而世界坐标是相对于场景的整体坐标系。
使用transform.position属性来获取物体在世界坐标系下的坐标。
使用transform.localPosition属性来获取物体在世界坐标系下的坐标。
使用transform.TransformPoint将局部坐标系转换为世界坐标系。
使用transform.InverseTransformPoint世界坐标系转换为局部坐标系。
public class Coordinate : MonoBehaviour
{
public GameObject SomeThing;
public Vector3 SomePoint;
void Start()
{
Debug.Log("世界坐标:" + transform.position);
Debug.Log("局部坐标:" + transform.localPosition);
Debug.Log("当前坐标:" + SomePoint);
Vector3 worldPoint = transform.TransformPoint(SomePoint);
Debug.Log("局部坐标转为世界坐标:" + worldPoint);
Vector3 localPoint = transform.InverseTransformPoint(worldPoint);
Debug.Log("世界坐标转为局部坐标:" + localPoint);
}
}
如果想让物体运动到指定的位置,通常情况下是参考世界坐标系。因为世界坐标系是整个场景的坐标系,而局部坐标系是相对于物体的父对象的坐标系。假设想让物体移动到坐标为(x,y,z)的位置,参照世界坐标与局部坐标的物体运动代码如下:
// 世界坐标下运动
transform.position = new Vector3(x, y, z);
// 局部坐标下运动
transform.localPosition = new Vector3(x, y, z);
如果想要实现多个物体以相同的速度按照顺序移动到不同的位置,可以参考下一节。
将一个由多个零部件组成的自定义模型导入unity中,希望实现该模型的部分拆卸过程。下面以共有11个拆卸步骤为例
在网上找了很多资料,目前想到的办法有利用协程或动画播放的方法(这里只做了协程的方法,动画的等我学会再加上)
1、首先是自定义的模型的拆卸,因此需要知道哪些零部件需要先拆,哪些后拆。
2、还需要考虑碰撞等干涉情况,因此下面代码中有的零部件出现了多次。
3、将所有需要拆卸的零部件创建一个空父对象,下面这个代码就挂载到空父对象上。
4、利用GameObject.Find()函数,找到每个零部件,并放在一个数组里面,便于后续对每个零部件进行操作。
5、将每个零部件需要移动的指定位置与运动时间,同样放在另外两个数组里面。
6、零部件的移动,我使用的是DOTween插件中的DOLocalMove方法。
DOTween插件解析
下面代码有待完善,如“每一步拆卸步骤所有的时间是不一样的,但速度应该是一样,这个我目前还不知道如何解决,只知道运动的位移相同的零件,其运动速度是一样的”
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class MoveTogether : MonoBehaviour
{
//物体数组
public GameObject[] objects;
//物体名称数组
public string[] Names;
//目标位置数组
public Vector3[] targetPositions;
//运动时间数组
public float[] moveTime;
void Start()
{
Names = new string[]
{
"一移动螺丝",
"一移动螺丝",
"中间部分",
"铁片1螺丝",
"铁片1",
"铁片2螺丝",
"铁片2",
"铁片3螺丝",
"铁片3",
"整体下方",
"整体下方" };
objects = new GameObject[Names.Length];
for (int i = 0; i < Names.Length; i++)
{
objects[i] = GameObject.Find(Names[i]);
}
targetPositions = new Vector3[]
{ new Vector3(0f, 0f, -0.5f), //一移动螺丝向下
new Vector3(3f, 0f, -0.5f), //一移动螺丝向右
new Vector3(0f, 0f, -0.8f), //中间部分向下
new Vector3(3f, 0f, 0f), //铁片1螺丝向外
new Vector3(3f, 0f, 0f), //铁片1向外
new Vector3(0f, -2f, 0f), //铁片2螺丝向外
new Vector3(0f, -2f, 0f), //铁片2向外
new Vector3(-3f, 0f, 0f), //铁片3螺丝向外
new Vector3(-3f, 0f, 0f), //铁片3向外
new Vector3(0f, 0f, -0.3f), //整体下方向下
new Vector3(3f, 0f, -0.3f) }; //整体下方向右
moveTime = new float[] { 1f,3f,2f,2f,2f,2f,2f,2f,2f,2f,3f };
StartCoroutine(Spilt_Merge());
}
IEnumerator Spilt_Merge()
{
//StepA.transform.DOLocalMove(targetStepA1, moveSpeed).SetEase(Ease.Linear);
for (int i = 0; i < objects.Length; i++)
{
if (i > 0)
{
yield return objects[i - 1].transform.DOLocalMove(targetPositions[i - 1], moveTime[i - 1]).WaitForCompletion();
}
yield return objects[i].transform.DOLocalMove(targetPositions[i], moveTime[i]).WaitForCompletion();
}
}
}