I'm VERY new at programming in unity and it really is not my forte.
But I really need help with this.
I need help making a code that will change places with two game objects (8 in total all need to be able to switch with eachother) I want to use the mouse left key click to work.
All I got this far is:
void OnMouseDown ()
{
transform.position = otherObject.transform.position;
}
but this doesn't do anything.. please help! :)
For OnMouseDown() message to work you have to attach a Collider component. Go to Component->Physics menu and select a collider that fits your object. Most likely you want to use a Box Collider.
To switch objects you can do this:
void OnMouseDown ()
{
Vector3 temp = transform.position;
transform.position = otherObject.transform.position;
otherObject.transform.position = temp;
}
Related
So me and some people are developing a VR game and we need to have it when the VR hand Presses the button Some objects are hidden so when the trigger on the collider is entered
So I have the function
public void update()
{
//Called once per frame
}
Private void Ontriggerenter(collider, other)
{
if ( other.tag == "Hand")
{
Copper.SetActive(false);
}
Where copper is a public game object
I still have the start and update functions not sure if that's the problem but the button clicks but the function is never triggered dose someone maybe know the problem
the "T" and "E" of OnTriggerEnter should be capitalized and OnTriggerEnter takes a variableof type Collider. I am not sure if you have configured the colliders correctly. Here is how the code should look like
Private void OnTriggerEnter(collider other)
{
if ( other.tag == "Hand")
{
Copper.SetActive(false);
}
}
You can check out this article on Unity Collision basics to get some basic idea.
In order for a Trigger collision to happen, both objects need to have colliders, at least one needs to have a non-kinematic Rigidbody component on the same object as the collider, at least one of the colliders needs to have the "IsTrigger" property set to true (checked).
Here is a link to a Chart about how to get different types of collisions.
Note that there is a difference between a Trigger and a Collision (OnTriggerEnter vs OnCollisionEnter).
I removed the trigger and just using the positions of the VR button and called the setactive when the pos changed. Thank you all for your help tho.
I have a game I am creating in Unity. It has a table with 30 cubes on it. I want a user to be able to shuffle the cubes on the table using their mouse/touch.
I am currently using a ray to get the initial table/cube hit point then accessing the rigidbody component on the cube to apply a force using AddForceAtPosition, happening in an OnMouseDrag. I am also pulling out my hair trying to figure out how to apply force in the direction from the mouse's last position to the hit point on the rigidbody of the cube.
Can someone please help me? An example would be great. I would share my code but I am a spaghetti code monster and fear criticism... Thanks much!
If I understood correctly, is something like this you want to achieve? https://www.youtube.com/watch?v=5Zli2CJGAtU&feature=youtu.be
If so, first you have to add your cubes and table to a new layermask, this step is only necessary if you don't want your ray to hit other colliders that might mess with your result.
After this you should add a tag to all the cubes you want to aplly the force, in my case I added a new tag called "Cubes".
You can search on youtube this if you don't know how to do it, there are plenty of tutorials to help you.
After that you create a new script and attach to the camera. Here is my script:
public class CameraForceMouse : MonoBehaviour
{
public LayerMask layerMask;
RaycastHit hit;
Vector3 lastPosition;
// Start is called before the first frame update
void Start()
{
lastPosition = new Vector3();
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButton(0))
{
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 200f, layerMask))
{
if (hit.transform.CompareTag("Cubes"))
{
Rigidbody rb = hit.transform.GetComponent<Rigidbody>();
Vector3 force = (hit.point - lastPosition).normalized * 55f;
rb.AddForceAtPosition(force, hit.point);
}
lastPosition = hit.point;
}
}
}
}
Just want to say that there are a lot of ways to achieve the same thing, this is the way I decided to do, but there are probably other (maybe even better) ways of doing this.
Explaining the code:
The first thing is a public LayerMask that before you play the game you will have to select your camera in your scene and look for the script on the editor in the right side and select witch layerMask you added to your cubes and table.
If you don't know how raycast works, here is the documentation: https://docs.unity3d.com/ScriptReference/Physics.Raycast.html but you can also search on youtube.
The important thing here is the new vector being created to define the direction of the force.
First we declare a global variable called LastPosition, and for every frame that we are clicking, we will check for a collision, and if this collision happens, we will then create a new vector going out of the last position the mouse was to the position the mouse is now Vector3 force = (hit.point - lastPosition), than we normalize it because we only care about the direction and multiply it by the amount of force we want, you can make it as a nice variable but I just put it there directly.
Then, after you've applied the force to the position the ray hit the object, you have to define that this is now your last position, since you are going to the next frame. Remember to put it outside of the Tag check, because this is checking if the object we collided with is the cube we want to apply the force or if it is the table. If we add this line lastPosition = hit.point; inside of this check it will only assign a new lastPosition value when we hit the cube, and would lead to bugs.
I'm not saying my answer is perfect, I can think of a few bugs that can happen, when you click outside the table for example, but is a good start, and I think you can fix the rest.
What I am trying to achieve at this point, is the following:
Let's say that we have a Cube game object and a SteamVR player.
The Cube object is on position y = 100 and the SteamVR player is on position y = 0.
I want to make it possible that the player can zoom in on the game object by doing the following:
-> Pressing both triggers and bringing the controllers close to each other will zoom in.
-> Pressing both triggers and bringing the controllers away from each other will zoom out.
I think u understand the effect that I want to create.
For my project I am using the SteamVR Unity plugin.
Could someone say me if this is possible and give me some insight on how to do this?
Thanks in forward.
Have an if statement checking for two inputs and move the camera position in the forward direction close and closer to the target. If you want to save the original camera position before zooming just store the Camera.main.forward before incrementing it.
pseudocode
public SteamVR_Input_Sources LeftInputSource = SteamVR_Input_Sources.LeftHand;
public SteamVR_Input_Sources RightInputSource = SteamVR_Input_Sources.RightHand;
public Vector3 currentZoom;
public Vector3 zoomAmount;
void update(){
if( SteamVR_Actions._default.Squeeze.GetAxis(LeftInputSource) && SteamVR_Actions._default.Squeeze.GetAxis(RightInputSource)){
currentZoom.forward += zoomAmount.forward; //increment zoom by whatever amount while
triggers are held
Camera.main.transform.forward = currentZoom;
}
}
I have not tested this, hence why I labeled it pseudocode, however, I hope this helps!
Thanks for reading. I tried posting this on unity answers, but it's been 24 hours and it's still not out of moderation, so maybe I'll have better luck here.
Background
I am very new to unity and know I must be missing some critical piece of knowledge to tie this together. I've created a blank game with some placeholder terrain and added a main camera to the 3d orthographic scene. I would like the user to be able to move the camera along a parallel plane to the ground.
What I've Done
I've added a starter camera codebehind I found online along with an event system, rigid body, ray caster, and a bunch of other things I saw online for this sort of thing. All of these components are in the same layer.
The Problem
My camera script's update method is hit when I put that in for testing but it doesn't receive any other events even though it implements the appropriate interfaces. I'm guessing I have something blocking the input from hitting the script or I do not have a component I need in order for those events to fire.
I'm testing on desktop for now but I want this to run on mobile (although from what I've read the events I'm subscribing to should be universal). Can anyone spot any oversights or deficiencies in my setup so far? Here are some screenshots.
Thanks!
My Setup
Edit: by request, here is the camera script I'm using. I know it doesn't do what I want yet but the issue I'd like to tackle right now is why it doesn't seem to be wired up correctly. Like I said, if I put an update method in here it is hit but none of my other logs are hit.
using UnityEngine;
using UnityEngine.EventSystems;
// The touch is in 2D but the scene is in 3D, so touch.x => scene.x, touch.y => scene.z, and nothing change (0) => scene.y since y is up
public class TouchCamera : MonoBehaviour,
IPointerDownHandler,
IDragHandler,
IPointerUpHandler
{
private Vector3 prevPointWorldSpace;
private Vector3 thisPointWorldSpace;
private Vector3 realWorldTravel;
private int drawFinger;
private bool drawFingerAlreadyDown;
public void OnPointerDown(PointerEventData data)
{
Debug.Log("Pointer down");
if (drawFingerAlreadyDown == true)
return;
drawFinger = data.pointerId;
drawFingerAlreadyDown = true;
prevPointWorldSpace = data.pointerCurrentRaycast.worldPosition;
// in this example we'll put it under finger control...
GetComponent<Rigidbody>().isKinematic = false;
}
public void OnDrag(PointerEventData data)
{
Debug.Log("Pointer drag");
if (drawFingerAlreadyDown == false)
return;
if (drawFinger != data.pointerId)
return;
thisPointWorldSpace = data.pointerCurrentRaycast.worldPosition;
realWorldTravel = thisPointWorldSpace - prevPointWorldSpace;
_processRealWorldtravel();
prevPointWorldSpace = thisPointWorldSpace;
}
public void OnPointerUp(PointerEventData data)
{
Debug.Log("Pointer up");
if (drawFinger != data.pointerId)
return;
drawFingerAlreadyDown = false;
GetComponent<Rigidbody>().isKinematic = false;
}
private void _processRealWorldtravel()
{
Debug.Log("Updating camera position");
Vector3 pot = transform.position;
pot.x += realWorldTravel.x;
pot.z += realWorldTravel.y;
transform.position = pot;
}
}
Final Edit for the Solution
Thank you very much to Juan Bayona Beriso for helping me in chat with this configuration. Here is what we ended up with that now works:
The camera object has a Rigidbody and Physics 2D Raycaster attached to it. The scene now has a new Canvas object with a Graphics Raycaster (blocking mask set to everything and blocking objects set to none) and an event system with the standalone input module enabled. That canvas also has a child UI object that covers the screen and has the camera script attached. As a curiosity, it required a text component in order for the script to start receiving the events -- this only made a difference when the Raycast Target option was selected. Screenshots below.
I think you are misusing the EventSystem, OnPointerDown, OnDrag and all those functions, they are called when you have a PhysicsRaycaster in your Camera object and you press or drag over an UI Element or and object with a collider.
In your code you don't have any of these, you have a camera so you are not actually pointer down over it or dragging on it.
You have two options:
Either put this script in a plane with a collider or GUI element that is inside the camera and moves with it, or use Input.GetMouseButtonDown, Input.GetMouseButtonUp in the Update function
I am a total beginner at Unity3d. I have some background in android programming, but no C# experience whatsoever. The first thing I am trying to do is to create a clone of flappy bird game, called flappy plane, according to this tutorial
http://anwell.me/articles/unity3d-flappy-bird/
The problem is, when I tried to write a script that allows player to move (player.cs) with the code
using UnityEngine;
using System.Collections;
public class player: MonoBehaviour {
public Vector2 jumpForce = new Vector2(0,300);
public Vector2 jumpForce2 = new Vector2(0,-300);
// Use this for initialization
// Update is called once per frame
void Update () {
if (Input.GetKeyUp("space")){
Rigidbody2D.velocity = Vector2.zero;
Rigidbody2D.AddForce(jumpForce);
}
}
}
I get an error "An Object reference is required to access non-static member 'UnityEngine.Rigidbody2D.velocity'". I have googled that and it is suggested to access Rigidbody2d with GetComponent().velocity,
so I changed
Rigidbody2D.velocity = Vector2.zero;
Rigidbody2D.AddForce(jumpForce);
with
GetComponent<Rigidbody2D>().velocity = Vector2.zero;
GetComponent<Rigidbody2D>().AddForce(jumpForce);
The error is gone and I am able to add the script to the object, still I don`t get the desired action - after I hit play the object turns invisible and just falls down, does not react to spacebar button. What am I doing wrong?
Thanks for the answer.
It's possible that you're not adding enough force to have the object move upwards.
There's technically nothing wrong with your code. (Although you do have somethings mixed up in your question). The problem is in the fact that you're not adding ANY force upwards every single frame.
Essentially, at the moment, your player object is in free-fall the instant you hit the play button, and you're adding a minuscule force to the player only on the frames that the space bar is pressed.
To solve this, here's what you should be doing
Add an upward force to counter-act the force of gravity every frame. You can do this in two ways.
a. Set the rigidbody's velocity.y to 0 BEFORE detecting the space bar (this is really a hacky way, but it'll suffice and doesn't need any more code)
b. Add an upward force to the player which will nullify the effect of gravity. Just use F = mg to get the value of force you'd need to add.
You could, alternatively set the isKinematic property to true by default on the Player's rigidbody, set it to false on pressing the space bar, and back to true after a few frames (5 - 6 frames)
make sure your player object and the ground both have BoxCollider2D colliders to keep above ground.
you could keep a reference stored for the rigidBody like Rigidbody2D myRigidbody;
then in start put myRigidbody = GetComponent<Rigidbody2D>(); then you would use like myRigidbody.AddForce(jumpForce); your jumpForce2 though is shooting your player downward you should not need it in a jump as the physics and gravity will apply with the rigidbody.
incase your input is not set up in the project settings try to fire the jump with
Input.GetKeyDown(KeyCode.Space);