Home Game Development digital camera – Find out how to rotate a 3D object based mostly on stick Enter and the conventional of the bottom’s floor? (Unity3D)

digital camera – Find out how to rotate a 3D object based mostly on stick Enter and the conventional of the bottom’s floor? (Unity3D)

0
digital camera – Find out how to rotate a 3D object based mostly on stick Enter and the conventional of the bottom’s floor? (Unity3D)

[ad_1]

I’m making a recreation the place I need to view an object from any angle and use an analog persist with rotate it based on this enter and the floor the thing is at the moment resting on. Here is a visualization of what I’m making an attempt to perform to stipulate my query:

(that is from a digital camera perspective, consumer’s view. Additionally that is “rework.ahead”, woops)
In the top left, diagram its the plane of the surface normal (in magenta). In the bottom left, its the input stick direction (purple) based on the view from the camera. On the right would be the output direction in which the object would travel (orange).

In the meanwhile I’m going about a number of the preliminary steps like this with a brief cylinder (assume a hockey puck):

  1. Take the typical regular under the puck utilizing 8 raycasts across the rim in direction of the bottom
  2. Use this common regular to have the puck mimic the floor’s common tilt
  3. Use the digital camera’s rotation to because the reference for figuring out the place the stick is pointing from the participant’s POV
  4. By way of the diagram, that is the step the place I would hope to calculate the orange arrow (the output route of the thing’s ahead route), however to date I can’t determine that half out.

To specify, I need to apply drive based mostly on the rework’s ahead route relative to the bottom so merely making use of drive on an XY airplane isn’t what I’m making an attempt to perform. Beneath is my finest try to date. It fails in that it does not activate the bottom based on its motion on the airplane.

// All of the objects I'm utilizing to seize/retailer the info
GameObject enter;
GameObject camera_Axis;

GameObject tank_Manager;
bool isGrounded;

GameObject base_Model; // The "puck's" mannequin
GameObject base_Collider; // The "puck's" collider
GameObject ground_Checker; // Object which casts the 8 rays straight down from puck rim
float groundMatchSpeed; // Pace the objects mimics the bottom floor
float turnSpeed; // Pace at which the thing would flip left and proper relative to the floor

float lastAngleLSFromOrigin;
Vector3 lastPosition;

PlayerControls moveControl;
Vector2 transfer;

void Awake()
{
    moveControl = new PlayerControls();
}
void OnEnable()
{
    moveControl.Gameplay.Allow();
}
void OnDisable()
{
    moveControl.Gameplay.Disable();
}

void Replace()
{
    Quaternion rotation = base_Collider.rework.rotation;

    transfer = moveControl.Gameplay.LeftStick.ReadValue<Vector2>();
    float LSx = transfer[0];
    float LSy = -move[1];
    Vector2 LS = new Vector2(LSx, LSy); // Stick inputs

    float angleLSFromOrigin = Vector2.SignedAngle(new Vector2(0f, -1f), LS);
    if ((LSx == 0) & (LSy == 0))
    {
        angleLSFromOrigin = lastAngleLSFromOrigin; // If there may be any enter, replace the angle
    }

    Quaternion relative = camera_Axis.rework.rotation;

    if (LS.magnitude >= 1)
    {
        lastAngleLSFromOrigin = angleLSFromOrigin; // If stick is past threshold, replace angle    
    }

    if (rotation == camera_Axis.rework.rotation)
    {
        relative = Quaternion.Inverse(rotation) * yRotation(camera_Axis.rework.rotation);
        // I'm going to be trustworthy, I do not keep in mind why this works and the way, however it's important. Fixes an issue the place the thing and digital camera align completely
    }

    // Decide floor tilt from hover check factors
    Vector3[] hover_Test_Normals = ground_Checker.GetComponent<check_Grounded>().hover_Test_Normals;
    Vector3 averagedNormal = new Vector3();

    for (int i = 0; i < hover_Test_Normals.Size; i++ ) 
    {
        averagedNormal[0] += hover_Test_Normals[i][0];
        averagedNormal[1] += hover_Test_Normals[i][1];
        averagedNormal[2] += hover_Test_Normals[i][2];
    }

    averagedNormal[0] = averagedNormal[0] / hover_Test_Normals.Size;
    averagedNormal[1] = averagedNormal[1] / hover_Test_Normals.Size;
    averagedNormal[2] = averagedNormal[2] / hover_Test_Normals.Size;

    Quaternion rotateTo = base_Collider.rework.rotation;
    rotateTo = Quaternion.FromToRotation(base_Collider.rework.up, averagedNormal) * rotateTo;

    // Discover vector of displacement from final body
    Vector3 displacmentSinceLastFrame = new Vector3(Mathf.Abs(base_Collider.rework.place.x - lastPosition.x), 0f, Mathf.Abs(base_Collider.rework.place.z - lastPosition.z));
    Vector3 displacementDirection = displacmentSinceLastFrame.normalized;

    var colliderStep = Time.deltaTime * groundMatchSpeed;
    var modelStep = Time.deltaTime * turnSpeed;

    // If grounded, mimic tilt of floor
    if (tank_Manager.GetComponent<tank_State>().isGrounded == true)
    {
        rework.rotation = Quaternion.Lerp(rotation, rotateTo, colliderStep);
        base_Model.rework.rotation = Quaternion.Slerp(rotation, rotateTo, colliderStep);
    }

    lastPosition = base_Collider.rework.place;
}

non-public Quaternion yRotation(Quaternion q)
{
    float theta = Mathf.Atan2(q.y, q.w);

    // quaternion representing rotation concerning the y axis
    return new Quaternion(0, Mathf.Sin(theta), 0, Mathf.Cos(theta));
}`

I might additionally prefer to voluntarily acknowledge I do not fully perceive Quaternions and could also be doing one thing silly in consequence. In that case, please let me know. Some other solutions?

[ad_2]

LEAVE A REPLY

Please enter your comment!
Please enter your name here