I m building a car game using Unity. I need to check if the system receive the input from Throttle Axis of Logitech steering wheel of from another joystick. So I have the first Joystick named "Logitech Steering wheel", and I can have also (but I could don't have the second Joystick) another Joystick named Hand Controller.
Now I configured this in my Input system of Unity project:
Vertical1, intercept the input from Logitech Steering Wheel Throttle from the accelerator pedal, HandCVertial1, intercept the input from the second Joystick.
Now I build the class IRDSPlayerControl and in this class I mapped this control like this:
/// <summary>
/// The throttle axis.
/// Asse acceleratore
/// </summary>
public string throttleAxis = "Vertical1";
/// <summary>
/// The throttle axis.
/// Asse acceleratore con l hand controller
/// </summary>
public string throttleHandControllerAxis = "HandCVertial1";
To move the car I have this code now:
if (!overrideThrottleAxis)
{
float acc = Input.GetAxis(throttleAxis);
Car.ThrottleInput = Mathf.Clamp((acc + 1f) / 2f, -1f, 1f);
}
I need to know which of the two joysticks is sending the command bearing in mind that they can both be connected and the car can accelerate both if I use the pedal on the logitech and the lever of the second joystick.
Related
I'm new to C# and Unity, but I'm trying to code an app with Unity which would play my customer's 3D Side by Side VR video. I'm using script from here https://docs.unity3d.com/ScriptReference/Video.VideoPlayer.html to get the video running and it works great, BUT it doesn't play as Side By Side VR video, but just a flat video with two screens for both eyes.
UnityEngine.Video has Video3DLayout.SideBySide3d enumeration (https://docs.unity3d.com/ScriptReference/Video.Video3DLayout.html) that could solve the problem, but I don't know what is the right syntax for that. Here is the code I have tried:
using UnityEngine;
using System.Collections;
public class Movie : MonoBehaviour{
enum Video3DLayout {No3D, SideBySide3D, OverUnder3D};
void Start(){
Video3DLayout myLayout;
myLayout = Video3DLayout.SideBySide3D;
// Will attach a VideoPlayer to the main camera.
GameObject camera = GameObject.Find("Main Camera");
// VideoPlayer automatically targets the camera backplane when it is added
// to a camera object, no need to change videoPlayer.targetCamera.
var videoPlayer = camera.AddComponent<UnityEngine.Video.VideoPlayer>();
// Play on awake defaults to true. Set it to false to avoid the url set
// below to auto-start playback since we're in Start().
videoPlayer.playOnAwake = false;
// By default, VideoPlayers added to a camera will use the far plane.
// Let's target the near plane instead.
videoPlayer.renderMode = UnityEngine.Video.VideoRenderMode.CameraNearPlane;
// Set the video to play.
videoPlayer.url = "movie.mp4";
// Start playback. This means the VideoPlayer may have to prepare (reserve
// resources, pre-load a few frames, etc.). To better control the delays
// associated with this preparation one can use videoPlayer.Prepare() along with
// its prepareCompleted event.
videoPlayer.Play();
}
}
I have feeling that I'm introducing the enumerations wrong way and I hope that someone could guide me to right direction. I have tried to use this tutorial https://unity3d.com/learn/tutorials/topics/scripting/enumerations to understand more about enumerations, but this way my code is not working.
There's 2 reasons why it isn't working. You're creating a new enum, instead of using the UnityEngine.Video.Video3DLayout enum. Also you're not assigning myLayout to the videoPlayer.
using UnityEngine;
using System.Collections;
using UnityEngine.Video;
public class Movie : MonoBehaviour
{
public Video3DLayout myLayout;
void Start()
{
// Will attach a VideoPlayer to the main camera.
GameObject camera = GameObject.Find("Main Camera");
// VideoPlayer automatically targets the camera backplane when it is added
// to a camera object, no need to change videoPlayer.targetCamera.
var videoPlayer = camera.AddComponent<UnityEngine.Video.VideoPlayer>();
videoPlayer.targetCamera3DLayout = myLayout;
// Play on awake defaults to true. Set it to false to avoid the url set
// below to auto-start playback since we're in Start().
videoPlayer.playOnAwake = false;
// By default, VideoPlayers added to a camera will use the far plane.
// Let's target the near plane instead.
videoPlayer.renderMode = UnityEngine.Video.VideoRenderMode.CameraNearPlane;
// Set the video to play.
videoPlayer.url = "movie.mp4";
// Start playback. This means the VideoPlayer may have to prepare (reserve
// resources, pre-load a few frames, etc.). To better control the delays
// associated with this preparation one can use videoPlayer.Prepare() along with
// its prepareCompleted event.
videoPlayer.Play();
}
}
I have a simple FPS where a player can fire a gun. I want the clients to see the bullet holes. I am trying to accomplish this by invoking a server side method when the client tries to fire the gun. The server side method should then raycast from the players camera and spawn a bullet hole for everyone to see..
I can get this to work partially by passing the player as a parameter to the server method. However, since my raycasting needs to be done based off the player camera, the bullet holes end up appearing at character height, since it's using the player and not the camera.
It won't allow me to pass a camera through. I have also tried creating an empty game object called bullet spawn and passing that through but I was getting a "object reference not set to instance of an object." This same error seems to surface for any Child element of the player I attempt to pass to the server side method.
I am unsure of the right way to accomplish this.
void Update()
{
if (isLocalPlayer)
{
if (Input.GetButton("Fire1"))
{
CmdFire(BulletSpawn);
}
}
}
[Command]
void CmdFire(GameObject Player)
{
Ray shooterRay = new Ray(Player.transform.position, Player.transform.forward);
if (Physics.Raycast(shooterRay, out Hit, 10000))
{
Debug.Log("player hit");
GameObject Bullet_Hole = (GameObject)Instantiate(BulletHole_Prefab, Hit.point, Quaternion.FromToRotation(Vector3.up, Hit.point));
NetworkServer.Spawn(Bullet_Hole);
}
}
Think about it this way. What is it that you need to fire your weapon? You need the firing point and the firing direction (in your simple case). So try to pass just that information. Your CmdFire should look like void CmdFire(Vector3 firingPoint, Vector3 firingDirection). Remember that when you pass the player gameobject, it gets serialized and sent to the server which causes a lot of unneeded network traffic. Stick to value types and simple objects for commands.
This is what ultimately led me to the solution. Thank you for the advice. I simply passed two Vector3 parameters as you suggested which represent the raycast position and direction. I can now shoot from both client and server and see the bullet holes on both as well. Here is the code that fixed it in case anyone runs into this later on:
void Update() {
if (isLocalPlayer) {
if (Input.GetButton("Fire1")) {
Vector3 FiringSpot = PlayerCam.transform.position;
Vector3 FireDirection = PlayerCam.transform.forward;
CmdFire(FiringSpot, FireDirection);
}
}
}
[Command]
void CmdFire(Vector3 firingPoint, Vector3 firingDirection) {
Ray shooterRay = new Ray(firingPoint, firingDirection);
if (Physics.Raycast(shooterRay, out Hit, 10000)) {
GameObject Bullet_Hole = (GameObject)Instantiate(bullet_Hole_Prefab, Hit.point, Quaternion.FromToRotation(Vector3.up, Hit.point));
NetworkServer.Spawn(Bullet_Hole);
Destroy(Bullet_Hole, 10);
}
}
I want my PS3 controller to control my unity game, and so far it isn't going well. I have it plugged into my computer via the USB cable it came with. My computer did not install any drivers when I plugged it in, but it did make a sound and Unity seems to have detected it, printing Joystick Connected (controller name here)
Unfortunately, beyond that the controller does absolutely nothing. I have gone to the input menu and have adjusted input according to this map: http://forum.unity3d.com/threads/ps3-button-map.89288/
but still get nothing. Not a single button does anything.
I should also mention if this helps, this is how I'm getting input:
void FixedUpdate()
{
float movehorizontal = Input.GetAxis("Horizontal");
float movevertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(movehorizontal, 0, movevertical);
rb.AddForce(movement * speed);
}
You need a special driver in order to get your PS3 controller to work on PC. I highly recommend ScpToolkit. It's the best one out there.
I created an own function within a script which should be executed as soon as there is a collision (using OnCollisionEnter).
The idea would be the following:
I have a ring which is steered by the key of the keyboard (Up and Down). Then I produced a sine wave wire with spheres which are moving from right to the left(in a sine wave manner). The player should not be able to move the ring trough the wire.
Therefore I add two colliders to the ring (an Up and a Down collider) and a collision script.
The problem is that sometimes the ring can me moved through the wire... when I press the Up key all the time. Even worse when I do nothing, then the ring should slides along the wire... but it does not.
I think the problem is related to the fact, that my own function is not executed every frame. Or what do you think? How can I execute my own function every frame?
Here the code of the collision script:
void OnCollisionEnter(Collision collUP)
{
if (collUP.gameObject.name == "Sphere(Clone)") {
Debug.Log ("Kollidiert mit UP");
controller.MoveRingDown ();
}
}
And here the code of the ring script in which I created an own function:
public void MoveRingDown() {
transform.position = transform.position + new Vector3 (0f, -tilt, 0f);
}
public void MoveRingUp() {
transform.position = transform.position + new Vector3(0f, tilt, 0f);
}
OnCollisionEnter is only called once, when the collision produces ( as its names reads ). I think what you need is OnCollisionStay, which is executed while the collision lasts.
public Transform OculusPlayerPrefab;
public Transform DefaultPlayerPrefab;
void Start() {
Transform player = OVRDevice.IsHMDPresent() ?
(Transform)Instantiate(OculusPlayerPrefab) :
(Transform)Instantiate(DefaultPlayerPrefab);
player.position = transform.position;
}
This should detect if the oculus rift HMD is connected and instantiate the oculus player prefab, otherwise the default. However, IsHMDPresent() returns false whether the Oculus Rift is connected or not. In the unity/oculus integration package however, OVRMainMenu uses the IsHMDPresent() method with the expected results.
As of (at least) Unity 2018.2, using the Oculus Utilities, the following works:
if (OVRManager.isHMDPresent) {
// headset connected
}
I'll add that you can subscribe to HMDMounted and HMDUnmounted events as well which is somewhat related:
OVRManager.HMDMounted += MyOnHMDMountedFunction();
OVRManager.HMDUnmounted += MyOnHMDUnmountedFunction();
Those will fire when you put on (HMDMounted) and/or take off (HMDUnmounted) your headset.
Unity now has a built-in way to detect this.
http://forum.unity3d.com/threads/simply-detecting-the-oculus-rifts-presence-solved.294089/#post-2368233
Docs: http://docs.unity3d.com/ScriptReference/VR.VRDevice-isPresent.html
Edit: this answer is from 2014 and based on Unity 4. You probably want
to use the other answers.
I found this method to be working best:
Ovr.Hmd.Detect() > 0
Also remember of the the HMDLost/HMDAcquired events, so you don't have to poll this every frame:
bool oculusPresent=false;
void CheckOculusPresence() {
oculusPresent=Ovr.Hmd.Detect() > 0;
}
void Start() {
CheckOculusPresence();
OVRManager.HMDAcquired+=CheckOculusPresence;
OVRManager.HMDLost+=CheckOculusPresence;
}
(oculus SDK 0.4.3/unity3d 4.5.5, OSX/Windows)