Problem with Vector3.MoveTowards
Please help me. I translated a code from javascript to c# here and the previous code worked. Now when i leftMouseClick somewhere i want the character to walk to there. code:
using UnityEngine;
using System.Collections;
public class characterMovementScript : MonoBehaviour {
public float smooth = 1f;
private Vector3 targetPosition;
public GameObject Target;
void Awake(){
targetPosition = transform.position;
}
void Update (){
if(Input.GetMouseButton(0))
{
Plane playerPlane = new Plane(Vector3.up, transform.position);
Ray ray= Camera.main.ScreenPointToRay (Input.mousePosition);
float hitdist= 0.0f;
if (playerPlane.Raycast (ray,out hitdist)) {
Vector3 targetPoint= ray.GetPoint(hitdist);
targetPosition = ray.GetPoint(hitdist);
Quaternion targetRotation= Quaternion.LookRotation(targetPoint - transform.position);
transform.rotation = targetRotation;
}
}
Target.transform.position = Vector3.MoveTowards (Target.transform.position, targetPosition, Time.deltaTime * smooth);
}
}
Please help me. Thanks in advance. Ethan.
UPDATE: When i run the game i get the following error:
UnassignedReferenceException: The variable Target of characterMovementScript has not been assigned.
You probably need to assign the Target variable of the characterMovementScript script in the inspector.
characterMovementScript.Update () (at Assets/scripts/characterMovementScript.cs:27)
Answer by dhore · Apr 07, 2016 at 06:56 AM
The error message that you edited into your question simply tells you that you haven't assigned a gameObject to the variable Target
in the inspector.
~
EDIT: think I found your problem..
So you're creating a Plane called playerPlane at transform.position
Then you're creating a ray which goes to where the mouse is clicking with an origin of transform.position (the camera's position)
Then you're setting hitdist using the function playerPlane.Raycast(ray, out hitdist)
And therefore the reason why hitdist is 0 every time is because the Plane.Raycast(Ray, out float)
function sets the 'out float' to the distance between the Ray's Origin and where the Ray intersects the Plane. In your case, the Ray's Origin and the Plane's Origin were both initialized to transform.position which means that there is 0 distance between them - hence why hitdist is 0 and then your Target is not moving.
What you should be using instead of a Plane is Physics.Raycast() - and you should use this variation of the function public static bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);
(it's the one at the bottom of the Docs page). You don't need to worry about the last 2 parameters, only the first 3 - so pass it your Ray, then a RaycastHit variable which will return information about the object that it hit, and then, of course, your maxDistance.
Also, you have an unnecessary variable Vector3 targetPoint
in your inner IF statement which you should remove as you've already got the global variable Vector3 targetPosition
Hope all that made sense :P
That's the problem. I did. I told my Network$$anonymous$$anager to attach the character to the "Target" veriable when the player joins a room.
void OnJoinedRoom(){
GameObject myCharacter = PhotonNetwork.Instantiate ("character", vSpawn, Quaternion.identity, 0);
Camera.main.GetComponent<character$$anonymous$$ovementScript> ().Target = myCharacter;
}
Please see the following question to this here
Still not working correctly...
using UnityEngine;
using System.Collections;
public class character$$anonymous$$ovementScript : $$anonymous$$onoBehaviour {
public float smooth = 1f;
private Vector3 targetPosition;
public GameObject Target;
void Update (){
if(Input.Get$$anonymous$$ouseButton(0))
{
Ray ray= Camera.main.ScreenPointToRay (Input.mousePosition);
RaycastHit hit;
Debug.Log ("Shot a ray!");
float hitdist= 0.0f;
if (Physics.Raycast(ray, out hit, 100)) {
targetPosition = ray.GetPoint(hitdist);
Debug.Log ("Wait for it....");
Quaternion targetRotation= Quaternion.LookRotation(targetPosition - transform.position);
Debug.Log ("changed rotation!");
transform.rotation = targetRotation;
}
}
Target.transform.position = Vector3.$$anonymous$$oveTowards (Target.transform.position, targetPosition, Time.deltaTime * smooth);
Debug.Log ("$$anonymous$$oved");
}
}
this is my code now with some debugers. -Now when i start it spams my console with "$$anonymous$$ove" (Debugger) and i don't know how it got there already. -When i left click to shoot a ray it shoots between 3-9 rays (as if i was holding the mouse button). -it doesn't even get to the part where he should rotate and move...
Please help me.... @dhore
Firstly, it's getting to your "$$anonymous$$ove" Debugger before you click the mouse because that line of code is outside of the IF statement - ie. it's just in the Update function so is being spammed every single frame regardless of what you're doing.
Secondly, your code is currently sending a ray out on every single frame that your left mouse button is sending input (ie. when it's held down). What you should do is change if (Input.Get$$anonymous$$ouseButton(0))
to if (Input.Get$$anonymous$$ouseButtonDown(0))
so that it only runs that code on the frame that you initially press the mouse button. (Docs page here for the function)
EDIT: You also need to replace this line targetPosition = ray.GetPoint(hitdist);
with this targetPosition = hit.transform.position;
and just delete the hitdist variable as it's not doing anything.
Thank you but if you don't $$anonymous$$d i'm going to keep disturbing you until this part is complete :P
changed the $$anonymous$$ouse function but now idk what happend it doesn't get to the rotation even.
moved the moving thingy into the second if. hope it would be ok.
Script:
using UnityEngine;
using System.Collections;
public class character$$anonymous$$ovementScript : $$anonymous$$onoBehaviour {
public float smooth = 1f;
private Vector3 targetPosition;
public GameObject Target;
void Update (){
if(Input.Get$$anonymous$$ouseButtonDown(0))
{
Ray ray= Camera.main.ScreenPointToRay (Input.mousePosition);
RaycastHit hit;
Debug.Log ("Shot a ray!");
float hitdist= 0.0f;
if (Physics.Raycast(ray, out hit, 100)) {
targetPosition = ray.GetPoint(hitdist);
Debug.Log ("Wait for it....");
Quaternion targetRotation= Quaternion.LookRotation(targetPosition - transform.position);
Debug.Log ("changed rotation!");
transform.rotation = targetRotation;
Target.transform.position = Vector3.$$anonymous$$oveTowards (Target.transform.position, targetPosition, Time.deltaTime * smooth);
Debug.Log ("$$anonymous$$oved");
}
}
}
}
Answer by Ckboyd89 · Apr 07, 2016 at 04:36 AM
Your script works perfectly fine when I paste it into an empty project. The error you are getting hints at targetPosition being null, however as a public variable it should be exposed in the Inspector. This does not seem to be the case on your end, though.
You may be able to temporarily fix this issue by adding the following function to your characterMovementScript class:
void Awake()
{
targetPosition = transform.position;
}
It didn't fix it. I think i confused some stuff there. Wait a sec.