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.
Related
I have a ball that have a continuous bouncing, and I want to move it left and right in the x Axis with the mouse, so it follow the mouse's X movement.
I made the script bellow, but the ball didn't move with mouse!
Ball Script:
private Vector3 pos;
public Camera cam;
public Rigidbody Ball;
public float Speed;
public static float GlobalGravity = -9.8f;
public float GravityScale = 1.0f;
bool isforce = false;
private void Start(){
Ball = GetComponent<Rigidbody>();
Ball.useGravity = false;
}
private void FixedUpdate(){
Vector3 gravity = GlobalGravity * GravityScale * Vector3.up;
Ball.AddForce(gravity, ForceMode.Acceleration);
}
void force (){
isforce = false;
Ball.AddForce(Vector3.up * Speed, ForceMode.Impulse);
}
private void Update(){
if (isforce == true){
force();
}
if (Input.GetMouseButton(1)){
Vector3 mousePos = Input.mousePosition;
Vector3 wantedPos = Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, transform.position.y, 10));
transform.position = wantedPos;
}
}
private void OnCollisionEnter(Collision collision){
isforce = true;
}
try this and let me know what happens. yours was set to right click, but i changed this one to left click, other than that i just sat the balls x to the raw x of the mouse input.
private void Update(){
if (isforce == true){
force();
}
if (Input.GetMouseButton(0)){
Vector3 mousePos = Input.mousePosition;
Vector3 wantedPos = transform.position;
wantedPos.x=Input.mousePosition.x;
transform.position = wantedPos;
}
}
When you use transform.position, the Unity Physics will no apply to the rigidBody. Find your mouse position relative to the ball and add Force in the X direction accordingly.
You have a couple of options depending on what it is you want.
Also as #Hamed answered, when using physics you don't want to update the transform directly but add force using the Rigidbody.
Force Constant relative to where the Mouse is
if (Input.GetMouseButton(0))
{
Vector2 force = Vector2.zero;
//Get the Balls current screenX position
float ballX = Camera.WorldToScreenPoint(Ball.transform.position).x;
//Check if Click was Left or Right of the Ball
if (ballX > Input.mousePosition.x)
{
//Click was Left of the Ball
force = new Vector2(-1f, 0f);
}
else if (ballX < Input.mousePosition.x)
{
//Click was Right of the Ball
force = new Vector2(1f, 0f);
}
//Adjust force amount to your suiting
Ball.Addforce(force * Time.deltaTime);
}
Force relative to the mouse movement
if (Input.GetMouseButton(0))
{
Vector2 force = Vector2.zero;
float mouseDelta = Input.GetAxis("Mouse X");
//Check if the Mouse is going Left or Right
if (mouseDelta < 0f)
{
//Click was Left of the Ball
force = new Vector2(-1f, 0f);
}
else if (mouseDelta > 0f)
{
//Click was Right of the Ball
force = new Vector2(1f, 0f);
}
// Update force relative to mouse movement
force = Mathf.Abs(mouseDelta) * force;
//Adjust force amount to your suiting
Ball.Addforce(force * Time.deltaTime)
}
Hastily written, look then write your own :)
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 am making a plat former game and I'm having a problem in the camera position of the game im imitating the camera movement of the 1st version of the super mario bros but every time I move my character the camera will go up until the character will disappear. How can I fix it?
public Transform playerPos;
public Transform rigthCamBoundary;
public Transform levelEnd;
Vector3 destination;
Vector3 velocity = Vector3.zero;
private void Start()
{
destination = Vector3.ClampMagnitude(levelEnd.position, 22.8f);
destination = new Vector3(destination.x, destination.y, 13.5f);
}
private void FixedUpdate()
{
if (Vector3.Distance(playerPos.position, rigthCamBoundary.position) < 13.7f)
transform.position = Vector3.SmoothDamp(transform.position, levelEnd.position, ref velocity, .14f, 8.5f);
}
To freeze the y-axis, get the y-axis value when the game runs. After using Vector3.SmoothDamp, change the y-axis to that variable you got before then apply it to your transform.
public Transform playerPos;
public Transform rigthCamBoundary;
public Transform levelEnd;
Vector3 destination;
Vector3 velocity = Vector3.zero;
float yPos;
private void Start()
{
destination = Vector3.ClampMagnitude(levelEnd.position, 22.8f);
destination = new Vector3(destination.x, destination.y, 13.5f);
//Get the default camera y pos
yPos = transform.position.y;
}
private void FixedUpdate()
{
if (Vector3.Distance(playerPos.position, rigthCamBoundary.position) < 13.7f)
{
Vector3 tempPos = Vector3.SmoothDamp(transform.position, levelEnd.position, ref velocity, .14f, 8.5f);
//Apply the default camera y pos
tempPos.y = yPos;
transform.position = tempPos;
}
}
Note that I don't know if this code is attached to the camera but this answer assumes it is. Otherwise the solution still remains the-same but you just have to change transform.position.y and transform.position to something else.
[SOLVED]
I've been following the Learn To Code By Making Games course (Block Breaker Section) from Udemy and I have a flippin' annoying issue. My paddle doesn't clamp properly to the values I put in. I would have had no trouble with this but I decided that I want a small menu on the left side with a speed controller, sound controller and lives. This means I cant just say that I want the paddle to stop on the edge of the screen.
Observed Behavior:
The paddle does not constrain itself to the area I put in. As the screen size changes the paddle will either go off the screen or will be stopped somewhere like the middle of the screen.
What I Want It To Do:
I want the paddle to stop when it hits the edge of my menu on the left and to stop when it hits the screen on the right. I also want this to stay the same as my screen size changes. So basically I need a mathematic equation that can determine these points and it needs to be able to adjust based on the screen size.
Here is my code for the paddle:
using UnityEngine;
using System.Collections;
public class Paddle : MonoBehaviour {
public Texture texture;
public void Update () {
Vector3 paddlePos = new Vector3 (0.5f, this.transform.position.y , 0f);
float mousePosInBlocks = Input.mousePosition.x;
paddlePos.x = Mathf.Clamp(mousePosInBlocks, //Left Vaule, //Right Value);
this.transform.position = paddlePos;
}
}
this happens because Input.mousePosition returns position of mouse on screen, not in world space. just convert mousePosition into world position, and then assign its value to mousePosInBlocks.
using UnityEngine;
using System.Collections;
public class Paddle : MonoBehaviour {
public Texture texture;
public void Update () {
Vector3 paddlePos = new Vector3 (0.5f, this.transform.position.y , 0f);
float mousePosInBlocks = Camera.main.ScreenToWorldPoint(Input.mousePosition).x;
paddlePos.x = Mathf.Clamp(mousePosInBlocks, leftValue, rightValue);
this.transform.position = paddlePos;
}
}
Edit: Sorry, not WorldToScreenPoint, ScreenToWorldPoint
Try just setting the paddlePos to the new vector you're creating (in world space):
public Texture texture; // if needed for something outside this code
private Vector3 paddlePos;
private float mousePosInBlocks;
private float xValue;
private float leftValue;
private float rightValue;
public void Update () {
mousePosInBlocks = Camera.main.ScreenToWorldPoint(Input.mousePosition).x;
//compute leftValue on this line
//compute rightValue on this line
xValue = Mathf.Clamp(mousePosInBlocks, leftValue, rightValue);
paddlePos = new Vector3 (xValue, transform.position.y , 0f);
transform.position = paddlePos;
}
EDIT Based on updated question title, the following should work:
public Texture texture; // if needed for something outside this code
private Vector3 playerPosOnScreen;
private float mousePosInBlocks;
public void Update () {
playerPosOnScreen = Camera.main.WorldToScreenPoint(transform.position);
if (playerPosOnScreen.x > Screen.Width) {
transform.position = Camera.main.ScreenToWorldPoint (new Vector3 (Screen.Width, transform.position.y, transform.position.z);
} else if (playerPosOnScreen.x < 0f) {
transform.position = Camera.main.ScreenToWorldPoint (new Vector3 (0f, transform.position.y, transform.position.z);
}
}
Try something like this: (pseudo code, untested, to give you an idea)
Please check the comment for each step.
public void Update () {
// left bound
Vector3 left = Camera.main.ViewPortToScreenPoint(new Vector3(0f, 0f, 0f));
// Menu width
left.x += fmyMenuWidth; // Width of menu
// Right bound
Vector3 right= Camera.main.ViewPortToScreenPoint(new Vector3(1f, 1f, 0f));
// Temporary position vector
Vector3 paddlePos = Vector3.zero;
// capture mouse x
float mouseX = Camera.main.ScreenToWorldPoint(Input.mousePosition).x;
// capture mouse y
float mouseY= Camera.main.ScreenToWorldPoint(Input.mousePosition).y;
// Combine and limit the position's X-value, should not go off screen menu's width---->screen's width
paddlePos.x = Mathf.Max(Mathf.Min(right.x, mouseX), left.x);
// Combine and limit the position's Y-value, should not go off screen 0---->screen's height
paddlePos.y = Mathf.Max(Mathf.Min(right.y, mouseY), left.y);
// Finally set the bounded position
this.transform.position = paddlePos;
}
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;
}
}