简体   繁体   中英

Unity3D : make cylinder stretch from one point to another

I'd like, at each frame, to move, scale and rotate a given cylinder so that it behaves like a 'rope' between two points.

I have this code at the moment, but it doesn't work at all like intended :

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);

As you can guess the two points are rightHandPosition and hookDestination. For now, the cylinder spawns at 'random' locations, with 'random' rotations and enormous scales.

How can I fix it ?

"Full" script :

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;
            }
        }
    }
}

A screenshot of the scene :

钩子行为(错误)

Let us assume that cubeStart is the starting point and cubeEnd is the end point. And "cylinder" is your cylinder, then

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);

    }
}

Tested with Unity3D 2018.1 My concept about rotation is based on quaternions solely.

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;

where rotAxis is the sum of 2 vectors ie the default cylinder orientation and the wanted orientation. Angle is 180 degrees because we want the cylinder to rotate around the rotAxis by 180 degrees. It is the definition of quaternion rotation (rotation around an axis).

fafase's comment was the right answer : use LineRenderer .

hookRender.SetPosition(0, rightHandPosition);
hookRender.SetPosition(1, hookDestination);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM