Sorry for a vague title, I'm trying to keep it short.
Anyway, I've been attempting to create a 3D grabbing script that involves the mouse. For some reason, the GameObject gets stuck in the same position no matter when I grab the ball or where I move my cursor.
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Grab: MonoBehaviour
{
public bool grabby;
void OnMouseDown()
{
grabby = true;
}
void OnMouseUp()
{
grabby = false;
}
// Update is called once per frame
void Update()
{
if (grabby)
{
transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition) + Camera.main.transform.forward * 10f;
}
}
}
I tried breakpoints, which does nothing. The variable grabby is also changing, so that's not the problem. The only other issue I can think of is my math. If it helps, the Grab script is placed on the object you are supposed to grab.
In 3D world, the computer doesn't recognize the mouse cursor where you think it is. To solve this, you can use the function ScreenPointToRay. for example:
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hitInfo))
{
// Do something...
Debug.Log(hitInfo.point + " " + hitInfo.collider.name);
}
hitInfo.point Will give you the point where the mouse cursor touches.
hitInfo.collider.name Will give the name of the object that the mouse cursor touches.
Related
I build my first game and want to Instantiate an object,
the player should be allowed to choose where to instantiate it. It should be on the ground(plane) and the object(cube) should follow the mousePos. That's where the problem occurs. I tried for hours now (at least 5) but can't figure it out. I tried raycast and screentoWorld stuff, but the object doesn't follow my mouse perfectly. The best i could get is, if i moved right, the cube moved right, same for all the other directions but it did not move the same speed as my mouse, so it was not at the same pos and i can't "OnMouseDown" it(except for the very middle of the screen) I use an Orthographic Camera, the speed the Cube is moving with the mouse seems to be dependent on my camera Size, but I want it to work in any size etc. Thanks for any help in advance.
This is my code:
using UnityEngine;
using System;
public class VorKasernenBau : MonoBehaviour
{
public static event Action<Vector3> onBuildBuilding;
public Camera cam;
public GameObject kasernePrefab;
private void Update()
{
moveMe();
}
private void OnMouseDown()
{
if (true/*if genug platz*/)
{
Instantiate(kasernePrefab, transform.position, Quaternion.identity, transform.parent);
if (onBuildBuilding != null)
onBuildBuilding.Invoke(transform.position);
Destroy(gameObject);
}
}
private void moveMe()
{
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.CompareTag("Ground"))
{
transform.position = hit.point + Vector3.up;
Debug.Log("test");
}
}
}
}
Update1:
The z Position seems to be okay, but the xPos isn't following perfectly.
I moved the object with another function. (cam.screentoworld and y value to 1) This problem is solved(even known i am not really happy with this solution), but another problem comes with it. if i move the screen in play mode (through drag and drop), the mousePos is not calculated right since the calculated mousepos isn't translated like the screen. Anyways have a great night and thanks for the help.
Vector3 pos = cam.ScreenToWorldPoint(Input.mousePosition);
transform.position = new Vector3(pos.x,1,pos.z);
I am new in Unity and trying to create an Android mobile game.
First, I decided to create a script called "SelectObject" that will move the objects, provided that the object has a collider.
I add this script to the "MainCamera" components, since we need to determine if the camera ray touched the object.
Here is the script "SelectObject":
using UnityEngine;
using System.Collections;
public class SelectObject : MonoBehaviour
{
void Start() {
}
public void Update()
{
if ((Input.touchCount > 0) && (Input.touches[0].phase == TouchPhase.Began)) {
Ray ray = Camera.main.ScreenPointToRay(Input.touches[0].position);
RaycastHit hit; //Declaring the variable hit, in order to further determine if the camera's ray touhed the object
if (Physics.Raycast(ray, out hit)) {
if (hit.collider != null) { //If the ray of camera touches the collider
hit.collider.GetComponent<Move>().Movement(); //Calling the "Movement" method from script "Move" to move the object
}
}
}
}
}
The Move class is a component of the "Cylinder" object that should move when you click on it.
Here is the "Move" class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour {
public float speedModifier; //Determine the speed of movement
public Touch touch; //Using this variable, we will determine if there was at least some touch on the screen
void Start() {
speedModifier = 2.01f;
}
public void Update() {
}
public void Movement() { //Creating a "Movement" method to call it in the "SelectObject" script
touch = Input.GetTouch(0);
if(touch.phase == TouchPhase.Moved) {
transform.position = new Vector3(transform.position.x + touch.deltaPosition.x * speedModifier, transform.position.y, transform.position.z + touch.deltaPosition.y * speedModifier);
}
}
}
But when I start the game, the cylinder still doesn't move.
What am I doing wrong?
Not 100% clear on what you're trying to do but have you tried passing your location into the Movement() method? Something like this.
public void Movement(Vector3 targetLocation) {
transform.position = targetLocation;
}
Then you'd call it like this.
Movement(Input.touches[0].position);
Just a note since I noticed your speed modifier. The way your code is currently set up is going to instanly move the object to the touch location. If you would like to have it smoothly move to it at a specified speed you'll need to look up Lerping or store the previous position, current, and target position.
I have a GameObject, let's call it editor, that follows the position of the mouse in the world using the below script:
using UnityEngine;
public class FollowCursor : MonoBehaviour
{
void Update()
{
Plane objPlane = new Plane(-Camera.main.transform.forward,
gameObject.transform.position);
Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
if (objPlane.Raycast(mouseRay, out float distance))
{
gameObject.transform.position = mouseRay.GetPoint(distance);
}
}
}
This editor object is used in many places, one of which is to control panning of the camera. I control this panning using the script below, which is attached to the main camera:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraControls : MonoBehaviour
{
FollowCursor editor;
Vector2 camPosOnClick;
Vector2 mousePosOnClick;
public Vector2 RelativeToCamera(Vector2 worldPoint)
{
return worldPoint - (Vector2)gameObject.transform.position;
}
public Vector2 RelativeToWorld(Vector2 camPoint)
{
return camPoint + (Vector2)gameObject.transform.position;
}
void Start()
{
editor = GameObject.FindWithTag("GameController")
.GetComponent<FollowCursor>();
}
void Update()
{
if (Input.GetMouseButtonDown(1))
{
camPosOnClick = gameObject.transform.position;
mousePosOnClick =
RelativeToCamera(editor.gameObject.transform.position);
}
if (Input.GetMouseButton(1))
{
Vector2 change = mousePosOnClick
- RelativeToCamera(editor.gameObject.transform.position);
gameObject.transform.position = camPosOnClick + change;
}
}
}
The intended behavior of this code is upon right clicking, the position of the editor (tracking the mouse position) and the camera are saved. Each frame, the distance between the current editor position and the saved position (which equates to the drag distance) is added to the camera's saved position.
I can see no reason this code shouldn't work, but nothing happens when I right click. The action of right clicking causes the editor object to stop tracking its position; the raycast it uses fails every frame after right-clicking. I cannot figure out what right-clicking is doing that affects this raycast, nor how to fix it. Is there a flaw in this code that I have missed?
I want to move my player around in my level without a NavMesh Agent.
I was thinking something about raycasting, but i have tried everything and even looked up videos and searched on google about it, can't seem to find anything that works
Plz help!
you can use this for moving to mouseclick position.
This method will move object or player to the position where mouse is clicked on screen.
sorry for syntax error i have typed directly here
using UnityEngine;
using System.Collections;
public class MouseMovement : MonoBehaviour
{
public float speed = 10f;
bool isplayermove = false;
// Use this for initialization
private void Start ()
{
Vector3 playerpos = transform.position;
}
// Update is called once per frame
private void Update ()
{
if (Input.GetKeyDown(KeyCode.Mouse0))
{
is moveplayer = true;
}
if(ismoveplayer)
{
Vector3 mousePos = Camera.main.ScreenToWorldPoint(new Vector3(input.mousepos.x,input.mousepos.y,input.mousepos.z);
transform.position = Vector3.MoveTowards(transform.position,new Vector3(mousepos.x,transform.position.y,mousepos.z),speed * time.deltatime);
if(transform.position == mousepos)
{
ismoveplayer = false;
}
}
}
}
Does somebody have any idea how to attach particle system to the collider in the script?
I have my character and I want to have blood particle system on the position of the tap on the head. I have managed to do this with the code below but now I need to move it together with the collider(with the character). Because when I move my character(I use LeanTouch script for this) the blood is left where it was created on the scene.
The code I use, it is on the Camera:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ActionOnTapOrClick : MonoBehaviour {
public ParticleSystem blood;
private void Update()
{
if(Input.GetMouseButtonDown(0))
{
Ray toTouch = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit rhInfo;
bool didHit = Physics.Raycast(toTouch, out rhInfo);
if(didHit && rhInfo.collider != null )
{
Debug.Log("You've tapped on the " + rhInfo.collider.name);
blood.transform.position = rhInfo.point;
Instantiate(blood, rhInfo.point, transform.rotation);
}
else { Debug.Log("You need to tap on the head!"); }
}
}
}
You're doing it right. All you need to do is to add your blood object as a child, so you can do something like this :
var ps = Instantiate(blood, rhInfo.point, transform.rotation); ps.transform.parent = transform;
So check out this and this depending on your Unity version
You should put in as a child object. This should work.
Instantiate(blood, rhInfo.point, transform.rotation, rhInfo.point.transform);
You must attach the particle to the character object