Rotating 2D world within Unity - c#

I am looking at developing a game within Unity by using C#
The game will take the gyroscope orientation and rotate accordingly to the direction of which the phone is rotated.
I am curious of how this would work, I understand how I would be able to read and update the gyroscope orientation however I am unsure on how to assign this to a world to rotate. There will be a player on world which will be the next challenge to prevent the player clipping through the world when it is rotated.
Hence the world should rotate around the players current location.
I currently have no code as I am in the process of designing this, however i am unable to get the logic of how to make this work within my head
Thankyou

If I get your objective right, I guess rotating the camera like in a Fist-Person game should be enough, and would be way simpler than rotating the whole world while keeping the player static.

This is how I would go about it, first I wouldn't rotate the world, as that is alot of objects to rotate, but if you really wanted to you could parent all of the world to a single game object, then rotate that object about an axis based off of the players position(See this: https://docs.unity3d.com/ScriptReference/Transform.RotateAround.html).
The simplest way is to attach your main camera to your player(Drag and drop it on your Player Object in your hierchy), then rotate your player.
for an example you can test on your machine without the gyroscrope:
using UnityEngine;
public class rotatorScript: MonoBehaviour {
void Update() {
// Will Rotate based off of left/right arrows
float rotator = -Input.GetAxisRaw("Horizontal");
// Move up or down based off of up/down Arrows
float verticalDirection = Input.GetAxisRaw("Vertical");
// Do the actual movement... using space.self so it is based on the player not the world.
transform.Translate(Vector3.up * verticalDirection * Time.deltaTime * 5f, Space.self);
transform.Rotate(0f,0f,90f * Time.deltaTime * rotator);
}
}
This script would be attached to the player.

Related

Using a Custom rotation in "Instantiate" - Unity 3D

I'am trying to make a throwing spear mechanic in my game.
The problem is that when i instantiate/spawn my "spear" its not facing the right direction i want it to be facing, forward in a 90 degree angle in the X and Y rotation. I tried to give it a rotation like this:
Instantiate(Spear.GetComponent(), transform.position, Quaternion.Euler(0,90,90));
but this only works if the player is in a specific position on the map (look image).
this is the code i have now:
clone = Instantiate(Spear.GetComponent<Rigidbody>(), transform.position,
Quaternion.Euler(0,90,90));
clone.velocity = transform.TransformDirection(Vector3.forward * ThrowForce);
You should give the rotation in the spear prefab and then just normally spawn it based on the prefab rotation like
Instantiate(Spear, position, Spread.rotation)
or if this doesnt work you can look at this
https://docs.unity3d.com/ScriptReference/Quaternion.LookRotation.html

How do I lock the rotation of a grabbed object with Unity Oculus VR

For an Oculus Quest game i'm working on, I need to be able to grab an object and not rotate it in any way. I should be able to move it in the x, y and z axes though. I'm doing this in a climbing game and the object is quite big. My player is locked on (0,0,0) and you climb by grabbing the terrain and moving it, giving the illusion that you are climbing.
I am using Unity's Oculus integration asset and I have the OVR Grabbable script on the object I want to be able to grab.
How do I make sure that the object I'm grabbing, doesn't rotate at all?
I've tried using a rigidbody and locking the rotation of the wall I want to climb like that, but that doesn't work. Once I grab it, I can still rotate the object.
I have also tried locking the rotation of the hand rigidbody, but that setting seemed to be ignored, because I could still rotate the hands.
I've also tried adding a bit of code in the script, which would reset the objects rotation in the fixed update. I put this code in the OVR Grabbable script.
void FixedUpdate()
{
transform.rotation = Quaternion.identity;
}
Using this code didn't keep the wall from rotating, but it did snap back to rotation (0,0,0) every frame. THis caused the wall to function as if it would still rotate, but it looked like it was switching between (0,0,0) and the rotation it would be at in every frame. This is of course also not the desired result.
I am not using VRTK, because that does not work with the type of climbing I'm trying to achieve.
I would like to be able to grab an object, move it in the x, y and z axes, while it doesn't rotate at all. Currently, I can still rotate the object. How would I fix this issue and completely lock the rotation whenever I grab the object?
If the object has become a child of the hand and you still want it to move but not rotate. You could add a simple script which scores its default rotation and applies it in LateUpdate.
This is designed for non-physics objects so be sure to remove your test where you added the rigidbody to the wall.
Something simple like this would do the job.
Quaternion defaultRotation;
void Awake()
{
defaultRotation = transform.rotation;
}
void LateUpdate()
{
transform.rotation = defaultRotation;
}

Get Unity Blend Tree to update based on player rotation (mouse position)

I'm working on the animations for a character in a top down game. I got the animations to work when the player is moving forwards towards the top, however, whenever I rotate the player with the mouse (to aim) the forward animation is now left/right, etc, etc. I'm using Unity3d and C# with blend tree animations.
The code I'm using is straightforward:
animator.SetFloat("VelX", playerInput.Horizontal);
animator.SetFloat("VelY", playerInput.Vertical);
I can't figure out how to make the forward animation play whenever I'm moving TOWARDS the mouse position.
My Solution:
var heading = Input.mousePosition - this.transform.position;
var distance = heading.magnitude;
var dir = heading / distance;
animator.SetFloat("VelX", playerInput.Horizontal * Mathf.Cos(dir));
animator.SetFloat("VelY", playerInput.Vertical * Mathf.Sin(dir));
Any help would be appreciated.
You may have figured this out already but I just had the same issue and I just found out a way to do this. Hopefully it helps others.
Vector3 inputVector = (Vector3.forward * Input.GetAxis("Vertical")) + (Vector3.right * Input.GetAxis("Horizontal"));
Vector3 animationVector = _playerModel.transform.InverseTransformDirection(inputVector);
var VelocityX = animationVector.x;
var VelocityZ = animationVector.z;
this._playerAnimator.SetFloat("x", VelocityX);
this._playerAnimator.SetFloat("z", VelocityZ);
I my case I have my movement script on a parent empty object. This object rotates the child player model, which is the one getting animated. If you do this then you will need to reference the player model like I am doing. Otherwise you can you transform if you are using the parent object.
I am using a character controller on my parent object not a rigidbody, but it may work the same either way.
From my understanding the key part is 'InverseTransformDirection' which is taking my physical world horizontal and vertical vectors and then converting them based on the rotation of my player model. This then makes the movements be relative to the players rotation rather than the worlds rotation and I can move backwards or strafe correctly as I am moving my mouse for rotation and wasd for movement.

Positioning a gun at a constant place

I am trying to position my gun the way most fps games position it,
for example like this:
But I'm having a problem when I try to position and rotate it with the player. The gun doesn't rotate well and doesn't have the same position always.
Is there a way to keep a gun in the same position and make it rotate well with the player?
But my main problem is the position of the gun i need it to stay in one place like in every fps, when i start the game and pick a gun it spawn in diffrent location on the screen Because of the rotation.
Here's is the code that I am trying to use:
GameObject temp = GameObject.Find(gameObject.name);
playerGuns[keyPress] = Instantiate(temp, Player.transform.position
+ new Vector3(-2f, 3f, 4f), Quaternion.identity) as GameObject;
playerGuns[keyPress].name = gameObject.name;
playerGuns[keyPress].tag = gameObject.tag;
playerGuns[keyPress].transform.parent = Player.transform;
playerGuns[keyPress].transform.rotation.SetLookRotation(Player.transform.position);
Alright here is the answer I promised:
First issue was with how you were setting your rotation, SetLookRotation takes in 2 parameters, Vector3 view, and Vector3 up the second is defaulted to Vector3.up. You were passing in the player.transform.position, for the "view" which is the direction you want transform to look in. Think of it like this, if I am far east facing west, my weapon will face east... (That is assuming the SetLookRotation normalizes it.) this is because my actual position is east, from some arbitrary origin. Something you could have used would have been player.transform.forward.
To spawn an object and have it have the same relative rotation and and position you can use Instantiate like you have in your original code. There are Several versions of instantiate.
In the comments I said to give yourself an offsetPosition and a eulerAngle, but this can be quite troublesome if you have multiple weapons. I mentioned I would give a recommendation for how I would set this up for multiple weapons... So here yea go.
Scriptable Objects,
In Unity you can create this objects to store information about a particular object, so for example a "Weapon" object can look like this:
using UnityEngine;
using System.Collections;
[CreateAssetMenu(fileName = "New Weapon", menuName = "Weapon")]
public class WeaponObject : ScriptableObject {
public string objectName = "New Weapon";
public Vector3 offSetPosition;
public Vector3 startOffsetRotation;
public float fireRate;
// Using a gameObject to store the weapon model so you can technical
// store the firing point.
public GameObject weaponModel;
}
You can create a new object now by right-clicking in your asset directory and going to create->weapon. Once you have done this you can rename the object it made, and the inspector will show all the public fields for this object you can modify.
With this you can create multiple weapons, and store their data in like a WeaponManager, that spawns every weapon. with something like:
WeaponObject weapon = WeaponManager.getWeapon(keyPress);
playerGuns[keyPress] = Instantiate(weapon.weaponModel, Player.transform.position + weapon.offsetPosition, Quaternion.identity) as GameObject;
playerGuns[keyPress].name = weapon.objectName;
playerGuns[keyPress].transform.parent = Player.transform;
playerGuns[keyPress].transform.eulerAngles = weapon.startOffsetRotation;
if(player.weaponScript != null) {
// we can have a single script for all of our weapons, and the WeaponObject
// will control its firerate, which projectiles it fires, etc.
player.weaponScript.setWeapon(weapon);
}
playerGuns[keyPress].transform.parent = Player.transform;
This line might be causing a problem. If you are parenting your gun to the players transform then it will follow the player. But it sounds like you want it to follow the camera?
try:
playerGuns[keyPress].transform.parent = Camera.main.transform;
Here is a useful answer provided by reddit user Mathias9807:
Many games will clear the depth buffer before drawing the gun model.
This will prevent the gun model from clipping through geometry but it
can look a bit weird when standing near a wall:
If you just want to render an object sticking to the camera you should
just get rid of the view matrix (Assuming you're using model-, view-
and projection matrices).
Explanation: Normally when you are using a view matrix (the camera matrix),the objects in the scene are being translated relative to the magnitude of the cameras position vector, and rotating by its yaw and pitch, which gives the illusion of a camera moving in a 3D space, but really there is no camera, just the objects in the scene that scale, and translate in in relation to the values defined for the camera.
So, when you remove that camera matrix for an object, the cameras position now has no influence on the models position, or put another way, the model does not move relative to the camera anymore but moves congruently with the camera.

How to fix object rotation and make it vertical in Vuforia?

I'm working on Vuforia application in Unity.
How can I make a 3D object, attached to the ImageTarget to always be vertical during the marker recognition?
So that if I will rotate the marker the model won't be upside down, but remain vertical. It should somehow "understand" were is the worlds z-axis, perhaps using sensors of the iPhone.
Here is an illustration of what I mean (grey square is a marker, a green guy is a 3D object, attached to it).
Currently if I will rotate the marker the model will also rotate:
I need to fix the rotation of the model along z-axis so that it always will remain vertical:
You can use Transfrom.LookAt () to make sure the object always camera facing, with Vector.Up as the 2nd argument:
using UnityEngine;
using System.Collections;
public class CameraFacing : MonoBehaviour
{
public Camera m_Camera;
void Update()
{
transform.LookAt(transform.position + m_Camera.transform.rotation * Vector3.forward,
m_Camera.transform.rotation * Vector3.up);
}
}
Attach this script to the image target's child (which will be shown on tracking is found). The camera is the AR camera you added in the scene.

Categories

Resources