- Home /
How to make Vector3s communicate with Floats?
I have slingshot function in my game (think Angry Birds) and I have set it up so that the character in the slingshot can only be pulled back a certain distance. However, the launch function that adds force to the character on launch follows the position of the mouse. In other words, when I click on the character and pull it back, I can pull it to a set distance away from it's starting point. But I can continue moving the mouse further away from the starting point, adding even more force, so when I release, the character flies much farther than they should. The launch code is using Vector3s to get the position, but Clamp.Magnitude uses the radius variable which is a float. Here's the code I have so far:
function Update()
{
//Raycast checks to see if squirrel is clicked on
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
var hit : RaycastHit;
if(Physics.Raycast (ray, hit, 100))
{
if(hit.transform.tag == "squirrel")
{
//gets mouse point in world space
var pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
pos.z = 0; //makes sure Z = 0
//drag squirrel while button pressed
if(drag)
{
//Positions squirrel at the mouse's location
transform.position = pos;
}
if(Input.GetMouseButtonDown(0))
{
drag = true;
startPos = pos; //save initial position
wasClicked = true;
}
}//Closes if(hit.transform.tag == "squirrel")
}//Closes if(Physics.Raycast...)
if(Input.GetMouseButtonUp(0) && wasClicked)
{
drag = false;
var dir = startPos - pos; //calculate direction and intensity
moveDirection = dir * launchForce; //launches with force input
Debug.Log(dir);
isLoaded = false; //frees squirrel from launch zone clamps
isLaunching = true; //allows squirrel to pass through the
//launchPoint triggerzone without being stopped
squirrelActive = true;//allows squirrel to begin moving freely
squirrelDirection = true; //tells squirrel to start moving right
//since they are always moving left
//after returning to the launch tree
wasClicked = false;
}
//Clamps squirrel to specified radius around launchPoint
var movement = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
var newPos = transform.position + movement;
var offset = newPos - centerPt;
transform.position = centerPt + Vector3.ClampMagnitude(offset,radius);
}// Closes function Update
Thanks for any help!
Trying to fix this made me realize another problem with my script. I needed to take the if(Get$$anonymous$$ouseButtonUp(0)) out of the raycast. Otherwise if I pulled back the mouse so far that it was no longer on the squirrel, it would not launch when released. So I modified my original post to reflect this change now.
But you didn't fix the problem that is causing the issue in your question (as outlined in my answer). You need to adjust the position of the Squirrel before you calculate 'dir' on line 30. Now it is done after, so 'pos' will be the mouse position. You need 'pos' to be the adjusted position of squirrel'.
Answer by robertbu · Oct 03, 2013 at 04:55 AM
Your issue is with the order you do things in this code. You correct/limit the distance the squirrel is from the start point in Lines 49 - 53. But you calculate 'moveDirection' on line 32 before you've corrected the position. That is on line 17 you set the squirrel position to the mouse position, so your launch code is using the mouse position for the launch (not the limited position). A fix is to move your correction/limiting code into the 'if (drag)' statement on line 14...or at least move it above the 'if (Input.GetMouseButtonUp(0))' on line 27.
Well, trying this definitely makes a difference. But unfortunately it gives me a strange effect. If I move it before the transform.position = pos; in the 'if(drag)' statement, it doesn't recognize the clamp at all. If I move it below that, it causes a weird jittering to happen where the squirrel constantly moves back and forth every frame between the mouse position and where it should be clamped to.
And the weird part is, it gives me two different effects depending on where it is when I release. Half the time it shoots normally (but beyond the distance it is supposed to travel since the mouse is pulled past the clamp) and half the time it shoots backwards and seems to ignore collisions as it flies off of the screen. I'm not really sure what's going on there.
I started to fix your code, and found additional problems. As one example, with Camera.main.ScreenToWorldPoint(), you need to set the 'z' parameter of the Vector3 passed to the distance in front the camera. Passing it just 'Input.mousePosition' will always return the position of the camera regardless of where the mouse is on the screen. Given that this script is attached to the squirrel, there are simpler solutions. The following code assumes the object is at 'z' = 0 and the camera is facing towards positive 'z'. Attach it to your squirrel. Note the two lines using rigidbody are there for my testing. I have no idea how you move your squirrels.
#pragma strict
public var radius = 1.5;
public var force = 500.0f;
private var offset : Vector3;
private var startPos : Vector3;
function On$$anonymous$$ouseDown() {
var pos = Input.mousePosition;
pos.z = -Camera.main.transform.position.z;
pos = Camera.main.ScreenToWorldPoint(pos);
offset = transform.position - pos;
startPos = transform.position;
}
function On$$anonymous$$ouseDrag() {
var pos = Input.mousePosition;
pos.z = -Camera.main.transform.position.z;
pos = Camera.main.ScreenToWorldPoint(pos);
var newPos = pos + offset;
transform.position= startPos + Vector3.Clamp$$anonymous$$agnitude((newPos - startPos), radius);
}
function On$$anonymous$$ouseUp() {
var dir = startPos - transform.position;
rigidbody.useGravity = true; // Launch it for testing
rigidbody.AddForce(dir * force);
}
Hey thanks. This is a much cleaner way off doing it than I was using. I tried to use On$$anonymous$$ouseDrag before but didn't have a lot of luck with it until now. However, this seems to ignore the clamp completely. $$anonymous$$y squirrel has a characterController attached so to add force I use:
private var moveDirection : Vector3 = Vector3.zero;
function On$$anonymous$$ouseUp()
{
moveDirection = dir * launchForce;
}
Not that it should matter, but just for reference. :P
I tested the code before I posted it, and the clamp worked fine. Start with an empty scene, add an object with a 'Z' position of 0, add a Rigidbody, turn off gravity, and add this script. You should see the clamp work. $$anonymous$$aybe your radius is different in the inspector than in the code?
Tried it with a new rigidbody and you're right. That works exactly how I need it to. I have my radius set correct in both inspector and code. I've gone over my script and can't figure out why it would be different for a characterController. Everything else works exactly as it should.
Answer by fafase · Oct 02, 2013 at 08:31 PM
I think what you need is get the vector direction between the starting and the actual position of the mouse. Get the magnitude. Define a max magnitude. If the current vector magnitude is smaller than the max magnitude, then draw the current vector, if it is greater then draw the max vector using the current direction.
Vector3 direction = GetDirectionFromMousePosition();
if(direction.magnitude < maxMagnitude)
{
// Use direction
}
else
{
Vector3 shooting = direction.normalized * maxMagnitude;
}
Your answer
Follow this Question
Related Questions
How do I perform math on Vector3.x or Vector4.x as if it were a float? 3 Answers
How to set a target position in Vector3.MoveTowards using a variable 2 Answers
Applying Constant Force on Multiple Axes Via Javascript? 1 Answer
How to limit the distance to Half of the Circle from its actual raidus 2 Answers
Javascript int to float 1 Answer