How can I disable orientation with Oculus Locomotion Controller? - unity3d

I am new to Unity and VR. I am working on a VR app using the Oculus Quest. I have set up a teleportation system based on the following tutorial video by Valem: https://www.youtube.com/watch?v=r1kF0PhwQ8E - but find that when I turn my head or use the thumbstick to oriented during teleportation, after landing I can be facing sideways and any further movement using the thumbstick appears to be incorrectly aligned - so when you try to move forwards you move sideways etc.
I presume my camera rig (which is a child of the OVRPlayerController) is facing the wrong way. This is backed up by the fact that some text I've placed in front of the rig appears to have shifted to the side instead of straight up front.
I just want a simple teleportation system so you move to the new location but do not orientate - instead you remain facing in the same direction as you started.
Is it possible to disable orientation? Or are there any recommended alternative solutions for a teleportation system?

i used this workaround to remove teleport orientation:
open TeleportDestination prefab
delete the orientation gameobject
hit play, then fix those scripts that referenced it
you'll also end up inside LocomotionTeleport.cs DoTeleport(), where it seems to set that teleport rotation (so probably enough if modify code here)
public void DoTeleport()
{
var character = LocomotionController.CharacterController;
var characterTransform = character.transform;
// removed orientation
//var destTransform = _teleportDestination.OrientationIndicator;
var destTransform = _teleportDestination.transform;
Vector3 destPosition = destTransform.position;
destPosition.y += character.height * 0.5f;
// removed orientation
//Quaternion destRotation = _teleportDestination.LandingRotation;// destTransform.rotation;
#if false
Quaternion destRotation = destTransform.rotation;
//Debug.Log("Rots: " + destRotation + " " + destTransform.rotation * Quaternion.Euler(0, -LocomotionController.CameraRig.trackingSpace.localEulerAngles.y, 0));
destRotation = destRotation * Quaternion.Euler(0, -LocomotionController.CameraRig.trackingSpace.localEulerAngles.y, 0);
#endif
if (Teleported != null)
{
//Teleported(characterTransform, destPosition, destRotation);
Teleported(characterTransform, destPosition, characterTransform.rotation);
}
characterTransform.position = destPosition;
//characterTransform.rotation = destRotation;
}

Related

how to make rigidbody slide on diagonal wall collision

I'm struggling a lot with moving Rigidbodies, currently I have this method to move player:
private void SimpleMove()
{
var scaledMovementSpeed = movementSpeed;
_isRunning = false;
if (Run)
{
scaledMovementSpeed *= runMultiplier;
_isRunning = true;
}
var trans = transform;
var forward = trans.forward;
var newDirection = Vector3.RotateTowards(forward, SimpleMoveVector, Time.fixedDeltaTime * rotationSpeed, 0.0f);
trans.rotation = Quaternion.LookRotation(newDirection, trans.up);
var velocity = _rigidbody.velocity;
var velocityChange = new Vector3(forward.x * scaledMovementSpeed, velocity.y, forward.z * scaledMovementSpeed) - velocity;
_rigidbody.AddForce(velocityChange, ForceMode.VelocityChange);
_isMoving = true;
}
Map is build out of simple cubes right now and the player has capsule collider on him with freeze rotation on all axes.
By tweaking force values a little bit I managed to get it to work properly without the need to check for collisions myself but
expected behavior of player going diagonally into wall is to slide perpendicular to its surface. When I get close to cube's corner character slides across but when I'm going diagonally into a wall character just stops. Haven't tried it with analog input yet.
Is there a way to properly make character slide (fe. put proper physics material on him, or the wall?) or do I need to explicitly check and manage these collisions myself for that?
I thought that my turn-and-then-go-forward method might be messing with proper colliding, but I made the turn instant and the behavior was exactly the same.

Unity / Mirror - Is there a way to keep my camera independent from the player object's prefab after start?

I'm currently trying to create a multiplayer game using mirror!
So far I've been successful in creating a lobby and set up a simple character model with a player locomotion script I've taken and learnt inside out from Sebastian Graves on YouTube (you may know him as the dark souls III tutorial guy)
This player locomotion script uses unity's package 'Input System' and is also dependent on using the camera's .forward and .right directions to determine where the player moves and rotates instead of using forces on the rigidbody. This means you actually need the camera free in the scene and unparented from the player.
Here is my HandleRotation() function for rotating my character (not the camera's rotation function):
private void HandleRotation()
{
// target direction is the way we want our player to rotate and move // setting it to 0
Vector3 targetDirection = Vector3.zero;
targetDirection = cameraManager.cameraTransform.forward * inputHandler.verticalInput;
targetDirection += cameraManager.cameraTransform.right * inputHandler.horizontalInput;
targetDirection.Normalize();
targetDirection.y = 0;
if (targetDirection == Vector3.zero)
{
// keep our rotation facing the way we stopped
targetDirection = transform.forward;
}
// Quaternion's are used to calculate rotations
// Look towards our target direction
Quaternion targetRotation = Quaternion.LookRotation(targetDirection);
// Slerp = rotation between current rotation and target rotation by the speed you want to rotate * constant time regardless of framerates
Quaternion playerRotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
transform.rotation = playerRotation;
}
It's also worth mentioning I'm not using cinemachine however I'm open to learning cinemachine as it may be beneficial in the future.
However, from what I've learnt and managed to find about mirror is that you have to parent the Main Camera under your player object's prefab so that when multiple people load in, multiple camera's are created. This has to happen on a Start() function or similar like OnStartLocalPlayer().
public override void OnStartLocalPlayer()
{
if (mainCam != null)
{
// configure and make camera a child of player
mainCam.orthographic = false;
mainCam.transform.SetParent(cameraPivotTransform);
mainCam.transform.localPosition = new Vector3(0f, 0f, -3f);
mainCam.transform.localEulerAngles = new Vector3(0f, 0f, 0f);
cameraTransform = GetComponentInChildren<Camera>().transform;
defaultPosition = cameraTransform.localPosition.z;
}
}
But of course, that means that the camera is no longer independent to the player and so what ends up happening is the camera rotates when the player rotates.
E.g. if I'm in game and looking to the right of my player model and then press 'w' to walk in the direction the camera is facing, my camera will spin with the player keeping the same rotation while my player spins in order to try and walk in the direction the camera is facing.
What my question here would be: Is there a way to create a system using mirror that doesn't require the camera to be parented to the player object prefab on start, and INSTEAD works by keeping it independent in the scene?
(I understand that using forces on a rigidbody is another method of creating a player locomotion script however I would like to avoid that if possible)
If anybody can help that would be greatly appreciated, Thank You! =]
With the constraint of your camera being attached to the player you will have to adapt the camera logic. What you can do is instantiate a proxy transform for the camera and copy that transforms properties to your camera, globally, every frame. The parent constraint component might do this for you. Then do all your transformations on that proxy.
Camera script with instantiation:
Transform proxy;
void Start(){
proxy = (new GameObject()).transform;
}
void Update(){
//transformations on proxy
transform.position = proxy.position;
transform.rotation = proxy.rotation;
}

Get Unity compass true north heading

I'm currently trying to implement a location-based AR app for Android using Unity C# and ARCore. I have managed to implement an algorithm which gets latitude/longitude and translates it to unity meters. However, this is not enough to place objects at a GPS location since the orientation of the world will be off if you do not align the unity scene with the real world orientation.
Anyway, the problem with the compass is that I cannot find a way to align an object with the true north.
I have tried aligning an object with true north by using
transform.rotation = Quaternion.Euler(0, -Input.compass.trueHeading, 0);
However this causes the object to constantly change rotation based on where my phone's heading so in a way true north is always changing.
What I am currently trying is:
var xrot = Mathf.Atan2(Input.acceleration.z, Input.acceleration.y);
var yzmag = Mathf.Sqrt(Mathf.Pow(Input.acceleration.y, 2) + Mathf.Pow(Input.acceleration.z, 2));
var zrot = Mathf.Atan2(Input.acceleration.x, yzmag);
xangle = xrot * (180 / Mathf.PI) + 90;
zangle = -zrot * (180 / Mathf.PI);
TheAllParent.transform.eulerAngles = new Vector3(xangle, 0, zangle - Input.compass.trueHeading);
This seems to be working better since the object will point towards a single direction with minimum shaking/jittering of the object due to erratic compass reading but points in one direction nonetheless. However, the problem with this is that it points to a different direction every time the app starts, so true north is never in one place according to the code. However the compass readings are fine as I have checked the readings against other GPS apps which implement a compass.
I have also tried transform.rotation = Quaternion.Euler(0, -Input.compass.magneticHeading, 0); but this gives the same always-changing result as the first one. Any help would be appreciated.
its how i solve this issue in my project
i wish it help you.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class newway : MonoBehaviour
{
GameObject cam;
void Start()
{
cam = Camera.main.gameObject;
Input.location.Start();
Input.compass.enabled = true;
}
void Update()
{
Quaternion cameraRotation = Quaternion.Euler(0, cam.transform.rotation.eulerAngles.y, 0);
Quaternion compass = Quaternion.Euler(0, -Input.compass.magneticHeading, 0);
Quaternion north = Quaternion.Euler(0, cameraRotation.eulerAngles.y + compass.eulerAngles.y, 0);
transform.rotation = north;
}
}
Possibly, your GameObject is rotating on its own axes, but you need your GameObject to pivot around the camera, or the center.
If that's the case, try creating another empty GameObject, and set its position to (0, 0, 0), or wherever you wish the center to be. Then add original GameObject as a child to this new one.
Apply your transform.rotation script to this new GameObject.

Unity Navmeshagent won't face the target object when reaches stopping distance

I'm trying to get the NPC to look at the main character when I'm talking to him. I need to make sure it looks natural and that he is facing me. I know I can do Transform.LookAt() but that is too instant and unnatural.
How do I rotate the navmeshagent to face my character when its stopped moving?
Try this out to control the body orientation - the slerp is adjustable to your desired rotation speed (https://docs.unity3d.com/ScriptReference/Quaternion.Slerp.html):
private void FaceTarget(Vector3 destination)
{
Vector3 lookPos = destination - transform.position;
lookPos.y = 0;
Quaternion rotation = Quaternion.LookRotation(lookPos);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, [fill in desired rotation speed]);
}
if(agent.remainingDistance < agent.stoppingDistance)
{
agent.updateRotation = false;
//insert your rotation code here
}
else {
agent.updateRotation = true;
}
This will rotate your agent when it's distance below the stoppingDistance variable. However it will look inhuman, so if you're going for a humanoid ai I'd recommend looking at the unity Mecanim demo (particularly the locomotion scene) as it has code and animations that will properly animate the agent.
Maybe try this Head Look Controller. It's very smooth and blends with animations!
Put the char in a game object and copy the navmesh from the char to the parent, uncheck enable in char. move any scripts up too.
Just spent 5 hours to find this.

Character starts walking automatically, without any input

I have a problem with Unity 4.0.0. When I play the AngryBots project or even when I make my own char with a simple walking script, it automatically walks without pressing any button.
I tried to uninstall Unity, I tried it with an older version of Unity, I even deleted it from the registry, but I still get the same behaviour. Why does that happen? Is it a bug, or am I doing something wrong?
var speed = 6.0;
var jumpSpeed = 8.0;
var gravity = 20.0;
private var moveDirection = Vector3.zero;
private var grounded : boolean = false;
function FixedUpdate() {
if (grounded) {
// We are grounded, so recalculate movedirection directly from axes
moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, 0);
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
if (Input.GetButton ("Jump")) {
moveDirection.y = jumpSpeed;
}
} // Apply gravity
moveDirection.y -= gravity * Time.deltaTime;
// Move the controller
var controller : CharacterController = GetComponent(CharacterController);
var flags = controller.Move(moveDirection * Time.deltaTime);
grounded = (flags & CollisionFlags.CollidedBelow) != 0;
}
#script RequireComponent(CharacterController)
I am using this script for all my walking chars and it works, but now its walking automatically.
The issue is something is providing movement axis input.
Generally it will be another device such as joystick etc. First step will be to unplug any other input devices you might have to test (Isolate the problem - then fix as required)
Another thing that may be causing it: I had the same issue but no other input devices plugged in. I found that a driver called VJoy virtual joystick (Installed as part of FreetrackNoIR) was setting movement axis values to 1 and -1 for each axis, thus resulting in the same problem.
Disabling this driver (Control panel, device manager, Human Interface devices) fixed it for me!
Good luck.
You have to use an "Animation" component, not an "Animator" one. (You can assign this by clicking on "Add Component", "Miscellaneous" and "Animation." This will contain the "Play Automatically" button you need.
I had this same thing happen to me. My characters would go UP and LEFT when I would move my mouse off of the Game window while in the editor and in my builds.
Go to "Edit, Project Settings, Input" and verify that your Horizontal and Vertical are set accordingly. Once I deleted the second set of inputs for Horizonal and Vertical in the InputManager, it stopped doing that.