When i press LMB i am rotating my player towards the mouse position, what i also want to do is simulate shooting. So when clicking LMB i want to create a line from the player position to the mouse position. My big issue is that my player is moving and i cant seem to figure out how to get the start position of the ray.
As of now the ray renders from vector3(0,0,0) to the mouse position, which is not what i want. I want it to render from the PLAYER position to the mouse position.
Here is my code:
void Update () {
transform.Translate (Vector3.down * Time.deltaTime * movementSpeed, Space.World);
if (Input.GetButtonDown("Fire1")) {
Vector3 mousePos = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, 10);
Vector3 lookPos = Camera.main.ScreenToWorldPoint (mousePos);
lookPos = lookPos - transform.position;
float angle = Mathf.Atan2 (lookPos.y, lookPos.x) * Mathf.Rad2Deg + 90;
transform.rotation = Quaternion.AngleAxis (angle, Vector3.forward);
if (Time.time > nextFire)
{
nextFire = Time.time + fireRate;
StartCoroutine (shotEffect());
laserLine.SetPosition (1,this.transform.position+lookPos);
}
}
}
If your code is attached to player and laserLine.SetPosition() sets beginning and ending for your line i think that:
laserLine.SetPosition (1,this.transform.position+lookPos);
should looks:
laserLine.SetPosition (this.transform.position,this.transform.position+lookPos);
Related
New to C# and Unity, trying to have a pointer that follows a player around in 2D space but it is bound within a circle of radius 4. My code below produces some odd behaviour, the cursor seems to move farther away from the player, and is not bound by the radius.
void Update()
{
Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
mousePos.z = Camera.main.transform.position.z + Camera.main.nearClipPlane;
Vector3 centerScr = Camera.main.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, Camera.main.nearClipPlane));
Vector3 direction = mousePos - centerScr;
direction = Vector3.ClampMagnitude(direction, 4f);
transform.position = mousePos + direction;
}
}
I'm having trouble with my Camera script. The Camera rotates around the player by using a pivot that's assigned as a child of the camera. This works with 2 arrows (I'm developing this game for mobiles, so they're touch arrows) that allow the camera to rotate left and right.
The problem is when the Camera goes behind a wall or a huge object and can't see anything. I looked for a solution and I see that many developers used the RaycastHit or something similar.
Here's my code, the goal is to get the Camera to go closer to the pivot when near a wall in order to avoid blocking the Camera view. Can anyone help me?
public Transform target1;
public Transform pivot;
protected ButtonLeft buttonLeft;
protected ButtonRight buttonRight;
public Vector3 offset;
public bool useOffsetValues;
public float rotateSpeed;
private void Start()
{
buttonLeft = FindObjectOfType<ButtonLeft>();
buttonRight = FindObjectOfType<ButtonRight>();
if (!useOffsetValues)
{
offset = target1.position - transform.position;
}
pivot.transform.position = target1.transform.position;
//pivot.transform.parent = target.transform;
//USE IF U WANT TO DISAPPEAR THE CURSOR
//Cursor.lockState = CursorLockMode.Locked;
//pivot.transform.parent = target.transform;
pivot.transform.parent = null;
// usa questa dopo la costruzione del livello1
//pivot.transform.position = target.transform.position;
}
private void Update()
{
pivot.transform.position = target1.transform.position;
if (buttonLeft.Pressed)
{
pivot.Rotate(0, -90 * Time.deltaTime, 0);
Debug.Log("rotate left");
}
if (buttonRight.Pressed)
{
pivot.Rotate(0, 90 * Time.deltaTime, 0);
Debug.Log("rotate left");
}
Ray ray = new Ray(pivot.transform.position, pivot.transform.position - transform.position);
RaycastHit hit;
/*float horizontal = Input.GetAxis("Mouse X") * rotateSpeed;
float horizontal = Input.GetAxis("Mouse X") * rotateSpeed;
pivot.Rotate(0, horizontal, 0);
pivot.Rotate(0, horizontal, 0);
Use this to make the camera rotate on Mouse Y axes*/
/*float vertical = Input.GetAxis("Mouse Y") * rotateSpeed;
target.Rotate(vertical, 0, 0); */
//move camera based on the current rotation of the target and the original offset
float desiredYAngle = pivot.eulerAngles.y;
//Use this float to set the x angle of player
float desiredXAngle = pivot.eulerAngles.x;
//Use this rotation only if you want to rotate on Y
//Quaternion rotation = Quaternion.Euler(0, desiredYAngle, 0);
//Use this if u want to rotate up&down on x axes
Quaternion rotation = Quaternion.Euler(desiredXAngle, desiredYAngle, 0);
transform.position = target1.position - (rotation * offset);
//transform.position = target.position - offset;
transform.LookAt(target1);
}
Good approach is when you do raycast from pivot to camera, and, if some obstacle found, put camera on a ray, a bit closer to pivot, than hit point. Like this: (pseudocode, not tested):
Vector3 origin = pivot.transform.position;
Vector3 direction = transform.position - pivot.transform.position;
float maxCameraDistance = 10;
Ray ray = new Ray(origin, direction);
RaycastHit hit;
if (Physics.Raycast(ray, maxCameraDistance))
{
Vector3 offsetFromObstacle = -direction.normalized * 0.1f;
transform.position = hit.point + offsetFromObstacle;
}
I am trying to make a simple game where I am shooting a projectile when the user touches the screen, I first spawn 8 projectiles (sprites) and when the user touches the screen I would like the top projectile to fly in the touch direction. I was able to do this; However, every time I shoot, the projectile goes in the wrong direction, here is an image which will illustrate the issue.
Obviously the image is still here but the object will continue flying until it goes out of the screen and then gets destroyed.
Here is the code snippet that handles this
GameplayController.cs
if (Input.GetMouseButtonDown(0))
{
Vector3 position = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0);
position = Camera.main.ScreenToWorldPoint(position);
GameObject target;
target = new GameObject();
target.transform.position = position;
Arrow comp = currentArrows[0].GetComponent<Arrow>();
comp.setTarget(target.transform);
comp.GetComponent<Arrow>().arrowSpeed = 12;
comp.GetComponent<Arrow>().shoot = true;
currentArrows.RemoveAt(0);
Destroy(target);
}
I know I am getting the mouse input here and not the phone touch and that's fine for me, later I will convert it to the touch input.
Arrow.cs
public bool shoot = false;
public float arrowSpeed = 0.0f;
public Vector3 myDir;
public float speed = 30.0f;
private Transform target;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if(shoot)
{
transform.position += transform.right * arrowSpeed * Time.deltaTime;
}
}
public void setTarget(Transform targetTransform)
{
this.target = targetTransform;
Vector3 vectorToTarget = target.position - transform.position;
float angle = Mathf.Atan2(vectorToTarget.y, vectorToTarget.x) * Mathf.Rad2Deg;
Quaternion q = Quaternion.AngleAxis(angle, Vector3.forward);
transform.rotation = Quaternion.Slerp(transform.rotation, q, Time.deltaTime * speed);
}
private void OnBecameInvisible()
{
print("Disappeared");
Destroy(gameObject);
Gameplay.instance.isShooting = false;
}
Vector3 position = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0);
I think that your problem is that you're getting the screen coordinates by click, not the world coordinates, which is actually two different things. In order to direct your projectile correctly you need to convert your screen coordinates to world like it's done here.
The next thing is how you move the projectile:
transform.position += transform.right * arrowSpeed * Time.deltaTime;
You're moving the projectile to the right and then rotating it somehow. Maybe you should try to move it with Vector3.Lerp, which will be easier and rotate it with Transform.LookAt.
I have a method that will rotate my object to the point my mouse just clicked on. However, my object only rotates as long as my mouse button is held down.
My main rotation method is this:
void RotateShip ()
{
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
Debug.Log (Input.mousePosition.ToString ());
Plane playerPlane = new Plane (Vector3.up, transform.position);
float hitdist = 0.0f;
if (playerPlane.Raycast (ray, out hitdist))
{
Vector3 targetPoint = ray.GetPoint (hitdist);
Quaternion targetRotation = Quaternion.LookRotation (targetPoint - transform.position);
transform.rotation = Quaternion.Slerp (transform.rotation, targetRotation, speed * Time.deltaTime);
}
}
I call this method inside the FixedUpdate method and I've wrapped it inside the following if statement:
void FixedUpdate ()
{
// Generate a plane that intersects the transform's position with an upwards normal.
// Generate a ray from the cursor position
if (Input.GetMouseButton (0))
{
RotateShip ();
}
}
However, the object will still only rotate as long as my mouse button is held down. I want my object to continue to rotate to the point my mouse just clicked until it reaches that point.
How can I amend my code properly?
It's only rotating while your mouse is down because that's the only time you tell it to rotate. In your FixedUpdate (which Imtiaj rightfully pointed out should be Update), you're only calling RotateShip() while Input.GetMouseButton(0) is true. That means that you only rotate your ship while the button is pressed.
What you should do is take that mouse event and use it to set a target, then continuously rotate toward that target. For instance,
void Update() {
if (Input.GetMouseButtonDown (0)) //we only want to begin this process on the initial click, as Imtiaj noted
{
ChangeRotationTarget();
}
Quaternion targetRotation = Quaternion.LookRotation (this.targetPoint - transform.position);
transform.rotation = Quaternion.Slerp (transform.rotation, targetRotation, speed * Time.deltaTime);
}
void ChangeRotationTarget()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Plane playerPlane = new Plane (Vector3.up, transform.position);
float hitdist = 0.0f;
if (playerPlane.Raycast (ray, out hitdist))
{
this.targetPoint = ray.GetPoint (hitdist);
}
}
So now instead of only doing the rotation while MouseButton(0) is down, we do the rotation continuously in the update and instead only set the target point when we click the mouse.
I want to drag my 2d object in unity2d using code with:
offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new
Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
Problem is that my camera is also moving along x axis so when I click on gameobject to drag it, it moves along x axis. I want to make this gameobejct static so it will be in its place and won't move? Any suggestions?
Instead of using absolute screen-centric position, you can try using the speed of the mouse pointer. Something like:
if(beingDragged) {
transform.position += new Vector3(Input.GetAxis("Mouse X"),
Input.GetAxis("Mouse Y"), 0);
}
Another option is to use a variable to track the camera's movement since the start of the drag. Then you can subtract this movement offset from your calculation, so that the dragging is done in "World Space" rather than "Screen Space"
Sorry, but I couldn't implement your suggestion. Here is the code for dragging the object, when OnMouseDown() it always gets the position of moving camera.
void OnMouseDown()
{
screenPoint = Camera.main.WorldToScreenPoint(gameObject.transform.position);
offset = gameObject.transform.position + Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
}
void OnMouseDrag()
{
Vector3 curScreenPoint = new Vector3(screenPoint.x, Input.mousePosition.y, screenPoint.z);
Vector3 curPosition = Camera.main.ScreenToWorldPoint (curScreenPoint);
transform.position = curPosition;
}
}