Unity3D:使圆柱体从一点延伸到另一点
Unity3D : make cylinder stretch from one point to another
我想在每一帧移动、缩放和旋转给定的圆柱体,使其表现得像两点之间的 'rope'。
我目前有这段代码,但它根本无法正常工作:
hook.transform.position = (rightHandPosition + hookDestination)/2;
hook.transform.localScale = new Vector3(0.5F, Vector3.Magnitude(hookDestination - rightHandPosition), 0.5F);
hook.transform.rotation = Quaternion.Euler(hookDestination - rightHandPosition);
如您所料,这两个点是rightHandPosition 和hookDestination。目前,圆柱体在 'random' 个位置生成,具有 'random' 个旋转和巨大的比例。
我该如何解决?
"Full" 脚本:
public class FirstPersonController : MonoBehaviour {
public GameObject hook;
bool isHooked = false;
Vector3 hookDestination;
Vector3 rightHandPosition;
void Start() {
hook.renderer.enabled = false;
rightHandPosition = hook.transform.position;
}
// Update is called once per frame
void Update () {
if (isHooked) {
hook.transform.position = (rightHandPosition + hookDestination)/2;
hook.transform.localScale = new Vector3(0.5F, Vector3.Magnitude(hookDestination - rightHandPosition), 0.5F);
hook.transform.rotation = Quaternion.Euler(hookDestination - rightHandPosition);
}
if (isHooked && !Input.GetMouseButton(1)) {
isHooked = false;
hook.renderer.enabled = false;
}
if (Input.GetMouseButtonDown (1) && !isHooked) {
Ray ray = GameObject.FindGameObjectWithTag ("MainCamera").camera.ViewportPointToRay (new Vector3 (0.5F, 0.5F, 0));
RaycastHit hit;
if (Physics.Raycast (ray, out hit) && hit.distance < 5000000 && hit.collider.tag != "Player") {
isHooked = true;
hookDestination = hit.point;
hook.renderer.enabled = true;
}
}
}
}
现场截图:
fafase 的评论是正确答案:使用 LineRenderer
.
hookRender.SetPosition(0, rightHandPosition);
hookRender.SetPosition(1, hookDestination);
让我们假设 cubeStart 是起点,cubeEnd 是终点。而"cylinder"是你的圆柱体,那么
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AlignCyl : MonoBehaviour {
GameObject cubeStart;
GameObject cubeEnd;
GameObject cylinder;
Vector3 endV;
Vector3 startV;
Vector3 rotAxisV;
Vector3 dirV;
Vector3 cylDefaultOrientation = new Vector3(0,1,0);
float dist;
// Use this for initialization
void Start () {
cubeStart = GameObject.Find("CubeStart");
cubeEnd = GameObject.Find("CubeEnd");
cylinder = GameObject.Find("Cylinder");
endV = cubeEnd.transform.position;
startV = cubeStart.transform.position;
}
// Update is called once per frame
void Update () {
// Position
cylinder.transform.position = (endV + startV)/2.0F;
// Rotation
dirV = Vector3.Normalize(endV - startV);
rotAxisV = dirV + cylDefaultOrientation;
rotAxisV = Vector3.Normalize(rotAxisV);
cylinder.transform.rotation = new Quaternion(rotAxisV.x, rotAxisV.y, rotAxisV.z, 0);
// Scale
dist = Vector3.Distance(endV, startV);
cylinder.transform.localScale = new Vector3(1, dist/2, 1);
}
}
使用 Unity3D 2018.1 测试
我关于旋转的概念完全基于四元数。
x=rotAxis.x * sin(angle/2) = rotAxis.x;
y=rotAxis.y * sin(angle/2) = rotAxis.y;
z=rotAxis.z * sin(angle/2) = rotAxis.z;
w = cos(angle/2) = 0;
其中 rotAxis 是 2 个向量的总和,即默认圆柱方向和所需方向。角度为 180 度,因为我们希望圆柱体绕 rotAxis 旋转 180 度。它是四元数旋转(绕轴旋转)的定义。
我想在每一帧移动、缩放和旋转给定的圆柱体,使其表现得像两点之间的 'rope'。
我目前有这段代码,但它根本无法正常工作:
hook.transform.position = (rightHandPosition + hookDestination)/2;
hook.transform.localScale = new Vector3(0.5F, Vector3.Magnitude(hookDestination - rightHandPosition), 0.5F);
hook.transform.rotation = Quaternion.Euler(hookDestination - rightHandPosition);
如您所料,这两个点是rightHandPosition 和hookDestination。目前,圆柱体在 'random' 个位置生成,具有 'random' 个旋转和巨大的比例。
我该如何解决?
"Full" 脚本:
public class FirstPersonController : MonoBehaviour {
public GameObject hook;
bool isHooked = false;
Vector3 hookDestination;
Vector3 rightHandPosition;
void Start() {
hook.renderer.enabled = false;
rightHandPosition = hook.transform.position;
}
// Update is called once per frame
void Update () {
if (isHooked) {
hook.transform.position = (rightHandPosition + hookDestination)/2;
hook.transform.localScale = new Vector3(0.5F, Vector3.Magnitude(hookDestination - rightHandPosition), 0.5F);
hook.transform.rotation = Quaternion.Euler(hookDestination - rightHandPosition);
}
if (isHooked && !Input.GetMouseButton(1)) {
isHooked = false;
hook.renderer.enabled = false;
}
if (Input.GetMouseButtonDown (1) && !isHooked) {
Ray ray = GameObject.FindGameObjectWithTag ("MainCamera").camera.ViewportPointToRay (new Vector3 (0.5F, 0.5F, 0));
RaycastHit hit;
if (Physics.Raycast (ray, out hit) && hit.distance < 5000000 && hit.collider.tag != "Player") {
isHooked = true;
hookDestination = hit.point;
hook.renderer.enabled = true;
}
}
}
}
现场截图:
fafase 的评论是正确答案:使用 LineRenderer
.
hookRender.SetPosition(0, rightHandPosition);
hookRender.SetPosition(1, hookDestination);
让我们假设 cubeStart 是起点,cubeEnd 是终点。而"cylinder"是你的圆柱体,那么
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AlignCyl : MonoBehaviour {
GameObject cubeStart;
GameObject cubeEnd;
GameObject cylinder;
Vector3 endV;
Vector3 startV;
Vector3 rotAxisV;
Vector3 dirV;
Vector3 cylDefaultOrientation = new Vector3(0,1,0);
float dist;
// Use this for initialization
void Start () {
cubeStart = GameObject.Find("CubeStart");
cubeEnd = GameObject.Find("CubeEnd");
cylinder = GameObject.Find("Cylinder");
endV = cubeEnd.transform.position;
startV = cubeStart.transform.position;
}
// Update is called once per frame
void Update () {
// Position
cylinder.transform.position = (endV + startV)/2.0F;
// Rotation
dirV = Vector3.Normalize(endV - startV);
rotAxisV = dirV + cylDefaultOrientation;
rotAxisV = Vector3.Normalize(rotAxisV);
cylinder.transform.rotation = new Quaternion(rotAxisV.x, rotAxisV.y, rotAxisV.z, 0);
// Scale
dist = Vector3.Distance(endV, startV);
cylinder.transform.localScale = new Vector3(1, dist/2, 1);
}
}
使用 Unity3D 2018.1 测试 我关于旋转的概念完全基于四元数。
x=rotAxis.x * sin(angle/2) = rotAxis.x;
y=rotAxis.y * sin(angle/2) = rotAxis.y;
z=rotAxis.z * sin(angle/2) = rotAxis.z;
w = cos(angle/2) = 0;
其中 rotAxis 是 2 个向量的总和,即默认圆柱方向和所需方向。角度为 180 度,因为我们希望圆柱体绕 rotAxis 旋转 180 度。它是四元数旋转(绕轴旋转)的定义。