0
votes

I have just started working on another project where one of the game mechanics is the ability to relocate a drone to the position of your mouse cursor.

Here is my code below where I have several problems(will specify)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class lightDrone : MonoBehaviour
{
Vector3 newPosition;

void Start()
{
    newPosition = transform.position + (0,0,10); //***Problem A***
}
void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        RaycastHit hit;
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out hit))
        {
            newPosition = hit.point;
            transform.position = newPosition; // ***Problem B***
        }
    }
}
}

Problem A - I am trying to have the new position = wherever the cursorhas clicked + 10 on the y axis so the "Drone" is seemed to be flying and not in the ground. This isn't achieving anything and is just giving me compiling errors.

I want the exact position to be (cursor.x, (public int (y)), cursor.z) but I have a very vague idea to do it.

Problem B -

Currently when I click my mouse, the object moves to the cursor but it seems to be just teleporting instantly. I want it to move at a certain speed and I think I need a public float to do so and change transform.position to translate.position but this again doesn't work.

Thank you in advance for answering my questions, I am trying to learn these new mechanics and how to code them. :)

1

1 Answers

1
votes

Problem A

If you want your new position to be where ever the cursor clicked + 10 on the y axis it makes no sense to put any of your code in Start(). That's for initialization only. It runs just once at the beginning of the scene. Just add the 10 to your newPosition in the Update() method.

Problem B

Setting transform.position to a certain value will make your transform instantly move to that position. If you want to do it over time you need to move your transform a few increments at a time. Since this introduces that "over time" element, you need to use a method that takes place over time, so you need coroutines, asyncs or you can use just the update method if you're a tiny bit crafty.

Also you need the ray to intersect and hit something. Like a flat plane, the ground, terrain, anything with a collider. If it doesn't hit anywhere then you won't have a new place to move to.

Code

using UnityEngine;

public class LightDrone : MonoBehaviour
{
    public float speed = 60.0f;

    // Our destination needs to be remembered outside a single iteration of
    // Update. So we put it outside of the method in order to remember it
    // across multiple frames.
    private Vector3 currentDestination;

    // We need to check if we're at the destination yet so we know when to stop.
    private bool notAtDestinationYet;

    // When we're closer to the destination than this tolerance, we decide that
    // we have arrived there.
    private float tolerance = 0.1f;

    private void  Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            RaycastHit hit;
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out hit))
            {
                var newPosition = hit.point;
                // You can add whatever height you want here. I added
                // just 2 instead of 10.
                currentDestination = newPosition + new Vector3(0, 2.0f, 0);
                notAtDestinationYet = true;
            }
        }

        if (notAtDestinationYet)
        {
            // Use a bit of vector math to get the direction from our current
            // position to the destination. The direction is a normalized Vector
            // that we can just multiply with our speed to go in that direction
            // at that specific speed!

            var heading = currentDestination - transform.position;
            var distance = heading.magnitude;
            var direction = heading / distance;

            // Check if we've arrived at our destination.
            if (distance < tolerance)
            {
                notAtDestinationYet = false;
            }
            else
            {
                // If the remaining distance between us and the destination is
                // smaller than our speed, then we'll go further than necessary!
                // This is called overshoot. So we need to make our speed
                // smaller than the remaining distance.

                // We also multiply by deltaTime to account for the variable
                // amount of time that has passed since the last Update() call.
                // Without multiplying with the amount of time that has passed
                // our object's speed will increase or decrease when the
                // framerate changes! We really don't want that.

                float currentSpeed = Mathf.Clamp(speed * Time.deltaTime,
                    Mathf.Epsilon, distance);
                transform.position += direction * currentSpeed;
            }
        }
    }
}