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!
Related
I want every step the player moves up the camera to move back one step in position z, and also the opposite when the player falls down.....
I really need someone to answer me I am new to making games and this problem stay with me for a long time so if anyone can help I will be so happy about that!!
So how to do it??
You can do this step to do the following task:
In your movement script get reference of your camera.
In your up movement function move your camera back in z axis by subtracting the amount you want camera to move :
float Step = 1; Camera.transofrm.position = new Vector3(Camera.transofrm.position.x,Camera.transofrm.position.y,Camera.transofrm.position.z-Step);
With this line of code your camera will go back in z each time player move up.
Do the same for fall down by just adding value to y axis of camera :
Camera.transofrm.position = new Vector3(Camera.transofrm.position.x,Camera.transofrm.position.y+Step,Camera.transofrm.position.z);
I am building a 3d topdown shooter. The player controls the avatar with the keyboard and the reticule with the mouse.
I found a simple way to implement the reticule based on this article:
https://gamedevbeginner.com/how-to-convert-the-mouse-position-to-world-space-in-unity-2d-3d/
I defined an object which represents the reticule and attached this script:
public class Reticule : MonoBehaviour
{
Camera mainCamera;
Plane plane;
float distance;
Ray ray;
// Start is called before the first frame update
void Start()
{
mainCamera = Camera.main;
plane = new Plane(Vector3.up, 0);
// This would be turned off in the game. I set to on here, to allow me to see the cursor
Cursor.visible = true;
}
// Update is called once per frame
void Update()
{
ray = mainCamera.ScreenPointToRay(Input.mousePosition);
if (plane.Raycast(ray, out distance))
{
transform.position = ray.GetPoint(distance);
}
}
}
This works, but the issue is that the reticule is lagging behind the mouse cursor, and catches up when I stop moving the mouse.
Is this because this method is just slow. Is there another simple way to achieve the same result?
the issue is that the reticule is lagging behind the mouse cursor, and catches up when I stop moving the mouse
That's normal, your mouse cursor is drawn by the graphics driver (with the help of WDM) as fast as the mouse data information comes over the wire, while your game only renders at a fixed framerate (or slower). Your hardware mouse will always be ahead of where your game draws it or anything related to it.
Some things that can help with working around this:
Don't show the system cursor, instead show your own. That way the cursor you show will always be in the same place your game thinks it is (since it drew it) and you won't have this issue. Careful with this however, because if your game's frame rate starts dipping it will be VERY noticeable when your cursor movement isn't smooth anymore.
Don't tie objects to your cursor. The issue doesn't show with normal interactions, like clicking buttons. You will notice this in RTS games when drawing boxes around units, but I struggle to think of another example of this.
Like above, but less restrictive, you could lerp the objects tied to your cursor in place, so they're always and intentionally behind it. It makes it look more gamey, which isn't that bad for a, you know, game. Though I wouldn't do this for a twitchy shooter, of course.
Currently I am working on a game for people with accessibility restrictions. I am having the issue of locking the player model in a sitting position. If the user does not center themselves in the room the player model will be pulled to a certain direction. I would like to lock the player model in a seat and only allow for arm movements and head rotations, no leaning or moving in the game using the HMD.
Since I am using the Final VR IK asset I have tried using their demo for sitting position in VR and cannot get the player to stay seated naturally. I am not sure how to program this or set restrictions to be able to do this.
Edit: To simplify my question. How do you lock the oculus rift HMD to only allow for rotation and not position tracking.
I figured it out how to lock the HMD into to only allow for rotation and not position tracking. To add a sitting position just use an body animation that's sitting. There are 2 things I did. First I added a line of code to the OVRCameraRig script:
trackingSpace.localPosition = -1 * centerEyeAnchor.localPosition;
This was done right before the RaiseUpdatedAnchorsEvent(); call around line 260 in the UpdateAnchors() method. What this does is it locks the head position and only allows for head rotation.
The second thing I did was write a head relocation script based on #derHugo answer to one of my other questions. What this does is when the space bar is pressed it will move the entire OVRCameraRig position. There must be a parent on OVRCameraRig for this to work In the screen shot below you can see the CameraParent object as the parent. I used a sphere as the relocation object that was placed in the middle of the head of my player model. The reason I had to add this was sometimes when you hit play the player would start at a weird position depending on where the headset was at the beginning. In the screen shot you can see use position tracking as not being checked in the inspector, that is an error. Please keep it selected to prevent screen tearing in the headset
Here is the code for the changing position of player when in game:
public class VRPositionChange : MonoBehaviour
{
public Transform resetPos;
private Transform parent;
private void Awake()
{
// create a new object and make it parent of this object
parent = gameObject.GetComponentInParent<Transform>();
}
// Update is called once per frame
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
// reset parent objects position
parent.position = resetPos.position;
}
}
}
I am trying to learn unity, and made my first own game and stucked at the beginning. The first idea was to drop a box (cube) to the mouse position. There are many videos and posts about getting the mouse position, and i tried to use them. My problem is, the mouse position i got is the camera's position, instead of the plane.
As you can see, it is kinda works, but it isn't fall to the plane.
https://prnt.sc/lmrmcl
My code:
void Update()
{
Wall();
}
void Wall()
{
if (Input.GetMouseButtonDown(0))
{
if (Input.GetMouseButtonDown(0))
{
wall = GameObject.CreatePrimitive(PrimitiveType.Cube);
Rigidbody wallsRigidbody = wall.AddComponent<Rigidbody>();
wall.transform.localScale = new Vector3(0.6f, 0.6f, 0.6f);
wallsRigidbody.mass = 1f;
wallsRigidbody.angularDrag = 0.05f;
wallsRigidbody.useGravity = true;
wallsRigidbody.constraints = RigidbodyConstraints.FreezeRotation;
wall.transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
Debug.Log(Camera.main.ScreenToWorldPoint(Input.mousePosition));
BoxCollider wallsCollider = wall.AddComponent<BoxCollider>();
wallsCollider.size = new Vector3(1f, 1f, 1f);
}
}
How should i change my code to get the right position?
This isn't a direct answer to your question, but I'm hoping it'll still get you where you need to go.
Prefabs are your friends! I'd highly recommend leveraging them here instead of constructing a cube directly in code.
But first, make sure everything else is set up right. Go ahead and construct a cube by hand in the Editor and make sure that when you hit Play, it falls as you expect. It should, provided it has a Rigidbody, collider, and you have gravity enabled (true by default).
If that works, drag that cube from your Hierarchy view into a folder in the Project view. This creates a prefab. You can now delete the cube from the Hierarchy view.
Update your script to have a public GameObject field, e.g.
public GameObject cubeToCreate;
Then, in the Inspector pane for whatever gameobject has that script attached, you should get a new field, "Cube To Create". Drag your prefab cube into that slot.
Lastly...update your code to wall = Instantiate(cubeToCreate). You'll still need to update the position, but you should be able to drop the rest of the initialization logic you have above, e.g. setting mass and drag.
As for the actual problem, the first thing that concerns me is how do you plan on turning a 2d mouse click into a 3d point? For the axis going "into" the screen...how should the game determine the value for that?
Camera.main.ScreenToWorldPoint accepts a Vector3, but you're passing it a Vector2 (Input.mousePosition, which gets converted to a z=0 Vector3), so the point is 0 units from the camera -- so in a plane that intersects with the camera.
I haven't done this, but I think you'll need to do raycasting of some sort. Maybe create an invisible 2d plane with a collider on it, and cast a physics ray from the camera, and wherever it hits that plane, that's the point where you want to create your cube. This post has a couple hints, though it's geared toward 2D. That might all be overkill, too -- if you create a new Vector3 and initialize it with your mouse position, you can set the z coordinate to whatever you want, but then your cube creation will be in terms of distance from the camera, which is not the best idea.
Hope this helps.
I'm coding a space-invaders like game, and I want to be able to move the player controlled ship with both mouse and keyboard. There is a speed constant that is being used, when moving the ship with the keyboard. When moving the ship with the mouse, only the position of the ship is changed. When moving the ship with the keyboard, the position of the mouse is also changed, to be consistent with the position of the ship.
The constant I mentioned is not an int value, but a float one. The reason behind this is that I want to add a powerup to increase the speed of the ship, and that may or may not be of type int. Also, I wish to be able to fine tune the speed, if requested by players or by game being to difficult. Problem is, the MouseState gives me a pair of int coordinates, but the position of the ship is a pair of float ones. So herein lies the problem :
Each frame, I need to move the ship to the mouse position (mouse controlled), and each frame I need to move the mouse position to the ship (keyboard controlled). Since the mouse gives me int coordinates, the float ones from the ship's position must be converted to int, which destroyes the idea I described earlier. Is there any way I can force the mouse to use float coordinates, either a workaround in XNA or some other API (DirectX or WINAPI)? I'm also toying with the idea of virtual coordinates and screen coordinates, with conversion between them.
Cheers,
Alex
EDIT : Added code snippet :
if (_keybState.IsKeyDown(Keys.Right))
{
Mouse.SetPosition(
(int)(_player1.GetPlayerPosition().X + Constants.HorizontalMovementSpeed),
(int)(_player1.GetPlayerPosition().Y));
}
if (_keybState.IsKeyDown(Keys.Left))
{
Mouse.SetPosition(
(int)(_player1.GetPlayerPosition().X - Constants.HorizontalMovementSpeed),
(int)(_player1.GetPlayerPosition().Y));
}
if (_keybState.IsKeyDown(Keys.Up))
{
Mouse.SetPosition(
(int)(_player1.GetPlayerPosition().X ),
(int)(_player1.GetPlayerPosition().Y - Constants.VerticalMovementSpeed));
}
if (_keybState.IsKeyDown(Keys.Down))
{
Mouse.SetPosition(
(int)(_player1.GetPlayerPosition().X),
(int)(_player1.GetPlayerPosition().Y + Constants.VerticalMovementSpeed));
}
if (_keybState.IsKeyDown(Keys.Space) && _shootKeyPressed == false)
{
_player1.Shoot();
_shootKeyPressed = true;
}
_shoboState = Mouse.GetState();
_player1.MovePlayerShipToPosition(new Vector2(_shoboState.X, _shoboState.Y));
Instead of tying the mouse and ship positions together like this:
_shoboState = Mouse.GetState();
_player1.MovePlayerShipToPosition(new Vector2(_shoboState.X, _shoboState.Y));
Try something along these lines:
Find unit vector between mouse and ship. This will give you a 1 unit step from your ship to your mouse. (You should be able to find tutorials for this fairly easily)
Multiply the unit vector by your movement amount. This gives you a direction and distance for you to move your ship.
Apply new vector to your ship.
Move the mouse as close as you can to your ship's new position.