I’m working on a small game where you can drag your finger across your mobile screen and it will create a line renderer from where ever you hit (using raycest) to where ever you released and depending on direction and how long the line is, adding force to a ball in the x and y direction based on the direction of the line created.
But my script doesn’t quite do this. I can draw a line with the line renderer and that looks perfect from start touch to touch release on the phone screen, however it doesn’t add force in the direction the line was drawn.
Can anybody help me with this direction issue based on my script (scroll down to the last function):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BallControl : MonoBehaviour
{
public float power = 50f;
public float maxDrag = 5f;
public Rigidbody rb;
public LineRenderer lr;
public Plane plane;
Touch touch;
public Color c1 = Color.magenta;
public Color c2 = Color.cyan;
// Start is called before the first frame update
void Start()
{
float alpha = 1.0f;
Gradient gradient = new Gradient();
gradient.SetKeys(
new GradientColorKey[] { new GradientColorKey(c1, 0.0f), new GradientColorKey(c2, 1.0f) },
new GradientAlphaKey[] { new GradientAlphaKey(alpha, 0.0f), new GradientAlphaKey(alpha, 1.0f) }
);
lr.colorGradient = gradient;
plane = new Plane(Camera.main.transform.forward * -1, Camera.main.transform.position);
}
// Update is called once per frame
void Update()
{
if (Input.touchCount > 0)
{
touch = Input.GetTouch(0);
if(touch.phase == TouchPhase.Began)
{
DragStart();
}
if (touch.phase == TouchPhase.Moved)
{
Dragging();
}
if (touch.phase == TouchPhase.Ended)
{
DragRelease();
}
}
}
RaycastHit hit;
Vector3 dir1;
Vector3 dir2;
void DragStart()
{
Ray mRay = Camera.main.ScreenPointToRay(touch.position);
if (Physics.Raycast(mRay, out hit))
{
dir1 = hit.point - transform.position;
dir1.y = 0;
lr.positionCount = 1;
lr.SetPosition(0, hit.point);
}
}
void Dragging()
{
Ray mRay = Camera.main.ScreenPointToRay(touch.position);
if (Physics.Raycast(mRay, out hit))
{
dir2 = hit.point - transform.position;
dir2.y = 0;
lr.positionCount = 2;
lr.SetPosition(1, hit.point);
}
}
//THIS IS THE CODE RESPONSIBLE FOR DIRECTION WHERE i NEED HELP:
void DragRelease()
{
lr.positionCount = 0;
Vector3 dragReleasePos = Camera.main.ScreenToWorldPoint(touch.position);
dragReleasePos.x = 0;
Vector3 force = dir1 - dir2;
Vector3 clampedForce = Vector3.ClampMagnitude(force, maxDrag) * power;
rb.AddForce(clampedForce, ForceMode.Impulse);
}
}
Also I’d like for it to not be possible to draw a line in negative direction and to stay within the plane it’s drawn on because right now the first touch can only happen on the plane, but I can still drag it way outside the planes contours. Thank you in advance for your help!
Do these coordinates of touch map 1-to-1 to your visuals? Usually touch is in screen coordinates, but things like LineRenderer would be in world coordinates.
You must find a way to get the information you need in order to reason about what the problem is.
What is often happening in these cases is one of the following:
the code you think is executing is not actually executing at all
the code is executing far EARLIER or LATER than you think
the code is executing far LESS OFTEN than you think
the code is executing far MORE OFTEN than you think
the code is executing on another GameObject than you think it is
To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.
Doing this should help you answer these types of questions:
is this code even running? which parts are running? how often does it run? what order does it run in?
what are the values of the variables involved? Are they initialized? Are the values reasonable?
are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)
Knowing this information will help you reason about the behavior you are seeing.
You can also put in Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene
You could also just display various important quantities in UI Text elements to watch them change as you play the game.
If you are running a mobile device you can also view the console output. Google for how on your particular mobile target.
Here’s an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:
You can use Vector3.Dot() to decide if a given vector is “in negative direction,” given whatever vector you want to consider being your “positive direction.”