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;
}
}
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;
}
}
So I have script which I got from Blackthornprods ranged combat youtube video since im a beginner. Im trying to get my weapon to rotate around my sphere gameobject but for some reason it doesnt rotate to where the mouse position is, but when I jump it rotates around weirdly not really to the mouse but randomly (im assuming randomly). My game is 3D and his tutorial was for 2d. I would really appreciate any attempt for a solution. Here is my code:
void Update()
{
Vector3 difference = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
float rotZ = Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0f, 0f, rotZ + offset);
}
The weapon is still to rotate around the Z axis.
First, Camera.main calls FindGameObjectsWithTag, which is an expensive operation, so (as the documentation says), you should call it as few times as possible and cache the result:
Camera mainCam;
void Awake()
{
mainCam = Camera.main;
}
Second, you're using ScreenToWorldPoint incorrectly. If this is really a 3d game as the question describes, you should provide a depth from the camera as the z component of the argument. You can use vector math to do this, and the result is a world position you can tread the cursor as being at.:
Camera mainCam;
void Awake()
{
mainCam = Camera.main;
}
void Update()
{
float objectDepthFromCamera = Vector3.Dot(
transform.position - mainCam.transform.position,
mainCam.transform.forward);
Vector3 cursorWorldPosition = mainCam.ScreenToWorldPoint(Input.mousePosition
+ Vector3.forward * objectDepthFromCamera);
Then assuming the "front" of the object points out of the local up direction, you can use the optional second parameter of Quaternion.SetRotation to set the rotation so that is pointing toward the cursor:
Camera mainCam;
void Awake()
{
mainCam = Camera.main;
}
void Update()
{
float objectDepthFromCamera = Vector3.Dot(
transform.position - mainCam.transform.position,
mainCam.transform.forward);
Vector3 cursorWorldPosition = mainCam.ScreenToWorldPoint(Input.mousePosition
+ Vector3.forward * objectDepthFromCamera);
transform.rotation = Quaternion.LookRotation(Vector3.forward,
cursorWorldPosition - transform.position);
}
If the front of the object points out the local right direction, you can use Vector3.Cross to determine what direction the local up should be pointing:
Camera mainCam;
void Awake()
{
mainCam = Camera.main;
}
void Update()
{
float objectDepthFromCamera = Vector3.Dot(
transform.position - mainCam.transform.position,
mainCam.transform.forward);
Vector3 cursorWorldPosition = mainCam.ScreenToWorldPoint(Input.mousePosition
+ Vector3.forward * objectDepthFromCamera);
Vector3 localUpNeeded = Vector3.Cross(Vector3.forward,
cursorWorldPosition - transform.position);
transform.rotation = Quaternion.LookRotation(Vector3.forward, localUpNeeded);
}
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.
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);
When I click right click I want to create new sphere. And I don't know why this don't work. It creates a sphere, but definitely not on mouse position!
Vector2 mousePos;
public Transform mousePointer;
float mouseX, mouseY;
Vector3 spawnPoint;
void Start () {
}
void Update () {
if(Input.GetMouseButtonDown(1)){
mousePos = Input.mousePosition;
mouseX = Input.mousePosition.x;
mouseY = Input.mousePosition.y;
spawnPoint = new Vector3(mouseX, mouseY, 0);
Instantiate(mousePointer, spawnPoint, Quaternion.identity);
}
}
Try spawning the object relative to the camera.
For example, use spawnPoint = cameraPosition + new Vector3(mouseX, mouseY, 0); or something similar. Check out the related post: Create a cube relative to camera mouse position.
The object is being spawned in global coordinates.