Steering object by head VR Cardboard - c#

Can somebody tell me how to do head based steering? I know how to do it while mooving only camera, but i want to moove object by head and camera to follow the object.
I need this because i want to implement game logic to the object(it will aleso work for me if i can treat camera as an normal object).
I found this code for steering only camera:
public float speed = /* some number */;
private CardboardHead head;
void Start()
{
head = // find the CardboardHead
// example:
// head = Camera.main.GetComponent<StereoController>().Head;
// or, make the variable public and use drag-and-drop in the Editor
}
void Update()
{
transform.position += speed * head.Gaze.direction;
}
I'm starting to make games for unity so if I made some mistakes please correct me.

Are you using cardboard plugin for Unity from here?
https://developers.google.com/cardboard/unity/download
if you do, then there is a prefab called cardboard main, put it in the scene, then if you see there is a game object called Head inside it and it contains CardboardHead script. So here is in your script:
public GameObject head; // drag the Head gameobject to here or you can just get it from the start
void Start()
{
if (!head) // if you didn't drag the gameobject
{
head = FindObjectOfType<CardboardHead>().gameObject;
}
}
void Update()
{
transform.position += speed * head.transform.forward; // it is better to multiply by Time.deltaTime
}
also btw why it is tagged as Java?
New questions:
So here is what I did. I split the 'visual' and 'mechanic'. I removed the Mesh Renderer from the player, freeze its rotation for the rigidbody. I made a new child for the 'visual' it has a Script called Rotate.cs and removed its collider.
Changes to script:
in Forward.cs use the rb.AddForce(transform.forward * speed); back, and in Rotate.cs just use
void Update () {
transform.Rotate(Vector3.right * 5);
}
That is the quickest solution I can think of, I'm sure there are other solutions which you can try

Related

Get other Players instantiated gameobjects Unity Photon

I am trying to access the Location of all the other Players who are connected to the same room. I first thought about getting the already instantiated gameobject but they all had the same name so that won't work. I wan't to to a Terrain Generator but when every Player generates Terrain its all messed up into each other. So i thought maybe just the first player has to generate the Terrain for himself and all other players to, but i now don't know how to get the other players positions. Therefore i can't check who is the first Player. So my second Question is: Is there maybe an other way to let only one generate the Terrain for all?
When i used the name to access my player i only got the player who i was already playing, i tried something where i send the player coordinates, but that only gives the coordinates when the photonView.isMine isnt True.
This is my Code so far this script is on the Player Prefab which gets instantiated when a player joins.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
public class NetworkPlayer : Photon.MonoBehaviour
{
private bool generatingTerrain;
private Vector3 correctPlayerPos;
private Quaternion correctPlayerRot;
private GameObject LevelGenerator;
private GameObject Player;
private float pos;
Rigidbody2D rb;
void Start()
{
LevelGenerator = GameObject.Find("LevelGenerator");
generatingTerrain = LevelGenerator.transform.Find("Level Generator");
Debug.Log(generatingTerrain);
if (photonView.isMine)
{
rb = GetComponent<Rigidbody2D>();
rb.simulated = true;
GetComponent<PlayerController>().enabled = true;
}
}
void Update()
{
//Debug.Log(generatingTerrain);
if (!photonView.isMine)
{
transform.position = Vector3.Lerp(transform.position, this.correctPlayerPos, Time.deltaTime * 5);
transform.rotation = Quaternion.Lerp(transform.rotation, this.correctPlayerRot, Time.deltaTime * 5);
Destroy(rb);
Debug.Log("Transform Position on !isMine: " + transform.position.x.ToString());
pos = transform.position.x;
}
Player = GameObject.Find("Player_1(Clone)");
if (photonView.isMine)
{
Debug.Log("photonView.isMine: " + transform.position.x.ToString());
Debug.Log("pos " + pos.ToString());
}
}
void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.isWriting)
{
// We own this player: send the others our data
stream.SendNext(transform.position);
stream.SendNext(transform.rotation);
}
else
{
// Network player, receive data
this.correctPlayerPos = (Vector3)stream.ReceiveNext();
this.correctPlayerRot = (Quaternion)stream.ReceiveNext();
}
}
}
Maybe i am just failing to see something, this is my first time working with unity and photon so i am really new to this topic.
If you need something just write me, i am sorry if something here is missing
Hope to get help soon :)
As far as getting the other players position you do it correctly, by looking at if the photonView is not mine.
I am not entirely sure what you are trying to do with the terrain. Right now you are trying to generate terrain on all players in the game which will make each player object in the game generate the terrain, which will probably cause chaos.
If you want to have procedurally generated terrain I would suggest doing it with a seed and then share the seed amongst all players. The terrain generation should then only be done if photonView.isMine.
If you want to change terrain, e.g. destroy or move blocks, then you need to sync this over the network , most likely with with Events or RPC calls.
I found a solution to my exact problem:
GameObject[] players = GameObject.FindGameObjectsWithTag("Player");
foreach (GameObject p in players)
{
Debug.Log(p.transform.position);
}
This lists every Gameobject which got the Player Tag and puts them into an Array, then you can access every of them to check that its not your own position you can just do:
if (p.position != gameobject.transform.position) {
//Do here what you want to do with every Player who isnt you
}
I found the solution here

What code do I need for my Unity character to shoot the bullet correctly?

I am not new to programming, but I am new to C#. I am experienced in Python, Java, and HTML. My game is 2D I have a game where my character currently has to touch the enemy to kill it. Now I added code for shooting a bullet to kill the enemy. I also want the bullet to be shot if the spacebar is pressed. The character is supposed to a shoot bullet in either direction. I have taken my code from an example my professor gave me which was originally Javascript and I converted it to C#. Unity no longer supports Javascript. The example code he gave me was basically a rocket shooting as many bullets as I clicked (clicking the mouse shoots bullets) to eliminate an enemy, however the rocket in that example does not move. In my game, the character moves, so the bullet has to get the position of the character. What is the correct code for getting the character position and shooting a bullet correctly?
I tested my game with my current code. The bullet is being spit out of nowhere (from the bottom of my background wallpaper [smack in the middle of the bottom] to a little below the wallpaper). Not even from the character...
Also, I added the Hit class script to my Bullet category in Unity.
Complete Camera Controller (no issues here at all)
using UnityEngine;
using System.Collections;
public class CompleteCameraController : MonoBehaviour {
public GameObject player; //Public variable to store a reference to the player game object
private Vector3 offset; //Private variable to store the offset distance between the player and camera
// Use this for initialization
void Start ()
{
//Calculate and store the offset value by getting the distance between the player's position and camera's position.
offset = transform.position - player.transform.position;
}
// LateUpdate is called after Update each frame
void LateUpdate ()
{
// Set the position of the camera's transform to be the same as the player's, but offset by the calculated offset distance.
transform.position = player.transform.position + offset;
}
}
Complete Player Control Class (If you read the comments in the code that say the "BULLET CODE", that's new code I have placed in the game for the bullets.
using UnityEngine;
using System.Collections;
//Adding this allows us to access members of the UI namespace including Text.
using UnityEngine.UI;
public class CompletePlayerController : MonoBehaviour
{
public float speed; //Floating point variable to store the player's movement speed.
public Text countText; //Store a reference to the UI Text component which will display the number of pickups collected.
public Text winText; //Store a reference to the UI Text component which will display the 'You win' message.
private Rigidbody2D rb2d; //Store a reference to the Rigidbody2D component required to use 2D Physics.
private int count; //Integer to store the number of pickups collected so far.
Rigidbody2D bullet;
float speed2 = 30f; //BULLET CODE
// Use this for initialization
void Start()
{
//Get and store a reference to the Rigidbody2D component so that we can access it.
rb2d = GetComponent<Rigidbody2D> ();
//Initialize count to zero.
count = 0;
//Initialze winText to a blank string since we haven't won yet at beginning.
winText.text = "";
//Call our SetCountText function which will update the text with the current value for count.
SetCountText ();
}
//FixedUpdate is called at a fixed interval and is independent of frame rate. Put physics code here.
void FixedUpdate()
{
//Store the current horizontal input in the float moveHorizontal.
float moveHorizontal = Input.GetAxis ("Horizontal");
//Store the current vertical input in the float moveVertical.
float moveVertical = Input.GetAxis ("Vertical");
Rigidbody2D bulletInstance; //BULLET CODE
//Use the two store floats to create a new Vector2 variable movement.
Vector2 movement = new Vector2 (moveHorizontal, moveVertical);
//Call the AddForce function of our Rigidbody2D rb2d supplying movement multiplied by speed to move our player.
rb2d.AddForce (movement * speed);
if(Input.GetKeyDown(KeyCode.Space)&& Hit.hit == false) //BULLET CODE IN HERE
{
// ... instantiate the bullet facing right and set it's velocity to the right.
bulletInstance = Instantiate(bullet, transform.position, Quaternion.Euler(new Vector3(0,0,0)));
bulletInstance.velocity = new Vector2(speed2, 0);
bulletInstance.name = "Bullet";
}
}
//OnTriggerEnter2D is called whenever this object overlaps with a trigger collider.
void OnTriggerEnter2D(Collider2D other)
{
//Check the provided Collider2D parameter other to see if it is tagged "PickUp", if it is...
if (other.gameObject.CompareTag ("PickUp"))
{
//... then set the other object we just collided with to inactive.
other.gameObject.SetActive(false);
transform.localScale += new Vector3(0.1f, 0.1f, 0);
//Add one to the current value of our count variable.
count = count + 1;
//Update the currently displayed count by calling the SetCountText function.
SetCountText ();
}
}
//This function updates the text displaying the number of objects we've collected and displays our victory message if we've collected all of them.
void SetCountText()
{
//Set the text property of our our countText object to "Count: " followed by the number stored in our count variable.
countText.text = "Count: " + count.ToString ();
//Check if we've collected all 12 pickups. If we have...
if (count >= 12)
//... then set the text property of our winText object to "You win!"
winText.text = "You win!";
}
}
Hit code. All code in this class is made for the bullet.
using UnityEngine;
using System.Collections;
public class Hit : MonoBehaviour
{
GameObject[] gameObjects;
public static bool hit = false;
void Removal ()
{
gameObjects = GameObject.FindGameObjectsWithTag("Bullet");
for(var i= 0 ; i < gameObjects.Length ; i ++)
Destroy(gameObjects[i]);
}
void OnCollisionEnter2D ( Collision2D other )
{
if(other.gameObject.name=="Bullet")
{
Removal();
Destroy(gameObject);
hit = true;
}
}
}
I see several issues with the code you wrote. as #Kyle Delaney suggested, I'd also highly recommend you check out the Unity Learn website, and go through several tutorials before moving through. I've highlighted a few issues below that may help solve your problem, but you could really benefit from changing your approach in the first place to avoid many of these issues. See below.
In your camera controller class, why not make the offset public so you can set it yourself in the inspector>
In Player controller class:
changed:
if (Input.GetKeyDown(KeyCode.Space)) //Shoot bullet
{
// ... instantiate the bullet facing right and set it's velocity to the right.
Rigidbody2D bulletRB = Instantiate(bullet, transform.position, transform.rotation);
bulletRB.AddForce(new Vector2(speed2,0), ForceMode2D.Impulse);
}
On a click, this instantiates the bullet prefab and sets its transform to copy the position and rotation of the player. It then adds a force to it to the right. You should avoid setting the velocity manually with rigidbodies, this can cause unwanted behaviour. Use the Addforce/addTorque methods instead. The ForceMode says to ignore its mass and set its velocity.
Then delete your Hit class, and replace with this Bullet class, which you drag onto the bullet prefab. Your player shouldn't be in charge of checking for bullet hits. that's the bullet's job. The player just launches the bullets and then the bullets do what bullets do. this just checks to see if the bullet hit anything, if so it destroys it. You can make this more complicated if you want. I would recommend using layers to determine which layers the bullet checks collisions with. You probably don't want bullets destroying your terrain. and you definitely don't want bullets destroying the player itself!
public class Bullet : MonoBehaviour
{
private void OnCollisionEnter2D(Collision2D collision)
{
Destroy(collision.gameObject);
Destroy(this.gameObject);
}
}
Also you shouldn't need to set the name of the bullet, since your prefab bullet should already be named "bullet".
I hope this gets you started in the right direction. But based on your code, I HIGHLY recommend you work through the tutorials before continuing with any projects. The unity staff that make them are super helpful and the tutorials start off really simple but get really complicated fast, so you actually come away learning a ton!
Perhaps the problem has to do with the player's parent transform. You could try something like this to make sure the bullet has the right parent:
bulletInstance = Instantiate(bullet);
bulletInstance.transform.parent = transform.parent;
bulletInstance.transform.position = transform.position;
bulletInstance.velocity = new Vector2(speed2, 0);
bulletInstance.name = "Bullet";
If that doesn't work it may be worthwhile to check the player's Rect Transform to see where the anchors and pivot are. Perhaps the player's actual "position" coordinates aren't where you think they are.
Have you done the Space Shooter tutorial? It has a segment about shooting bullets.

Building a rotatable lift in Unity

I got a "cube" in Unity. This cube has a Trigger, when moving into it, the object gets grabbed into the air. This is working as a lift, you can see an example what I mean here. It is a small scene taken from Spyro 2.
https://youtu.be/f8wWMa4N5mE?t=643
The code I use is really small for now
private float liftSpeed = 10; // the speed, the object is flying up
private void OnTriggerStay(Collider col)
{
Rigidbody objectRigid = col.gameObject.GetComponent<Rigidbody>(); // get the rigidbody from the object in the trigger
if (objectRigid != null) // does it have a rigidbody?
objectRigid.velocity = new Vector3(objectRigid.velocity.x, liftSpeed, objectRigid.velocity.z); // make it fly in the air
}
So I have a lift, that totally works fine. But I when I rotate my lift I want it to work aswell.
Some examples (my gamne is 3D)
So how can I make my lift work for all "rotations"?
You can use transform.up to get the up direction of your lift, and then multiply by the lift speed.
objectRigid.velocity = transform.up * liftSpeed;
transform.up changes depending on how the object is rotated, so if your lift is rotated to the left, then the lift will carry objects to the left.
You can use the transforms RotateAround Method for a rotation like in the video clip.
Transform t = col.gameObject.GetComponent<Transform>();
transform.RotateAround(Vector3.zero, Vector3.up, 20 * Time.deltaTime);
The given snipet lets the object rotate around it's axis, which is pointing up.
Make the player child of the lift OnTriggerEnter.
Move the lift as you do
You can rotate the lift using RotateAround function. The player should also rotate along with the lift, as it's a child of the lift now.
make player's parent to null when it's out of lift trigger using OnTriggerExit
This is my solution to the problem.
The lift and the EndPoint will be Empty GameObjects. If you want the lift has a platform or a base you can add a GameObject as child of the lift with the shape you prefer.
You need to attach a Collider to the lift and set it as trigger.
Then you add the following script to the lift Empty GameObject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveLift : MonoBehaviour {
public Transform end;
float speed = 4f;
bool liftActivated = false;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if(liftActivated)
{
float step = speed * Time.deltaTime;
//To move up the lift
transform.position = Vector3.MoveTowards(transform.position, end.position, step);
//To spin the lift
transform.RotateAround(Vector3.up, 2 * Time.deltaTime);
//To stop spining the lift when it reaches the end of the path
if(transform.position.Equals(end.position))
liftActivated = false;
}
}
void OnTriggerEnter(Collider other){
liftActivated = true;
other.gameObject.transform.parent = this.transform;
other.gameObject.GetComponent<Rigidbody>().isKinematic=true;
}
}
Then you should decide if once the lift reaches its destination it is the player who has to move out of the platform, or if you unparent it and let it fall down as the end of the trip

How to have a powerup have a slight chance of spawning when killing an enemy?

so we have a class assignment and pretty much we are doing the Survival Shooter project from the Unity tutorials. I've managed to make health packs and little boxes that give you speed when you pick them up, but now I want the power-ups to have a slight chance of dropping when enemies die. Can someone help me out? I'm not really asking for entire code, I have some down below:
public float percentDrop = 50f;
public GameObject HealthPack;
void Awake()
{
HealthPack = GetComponent<GameObject>();
}
public void TakeDamage (int amount, Vector3 hitPoint) { if(isDead) return;
enemyAudio.Play ();
currentHealth -= amount;
hitParticles.transform.position = hitPoint;
hitParticles.Play();
if(currentHealth <= 0)
{
Death ();
}
}
void Death ()
{
isDead = true;
capsuleCollider.isTrigger = true;
anim.SetTrigger ("Dead");
enemyAudio.clip = deathClip;
enemyAudio.Play ();
var randChance = Random.Range(0f, 100f);
if (randChance < percentDrop)
{
//GameObject.Healthpack.setActice(true);
}
}
I'm not too sure how to make the Game Object spawn when they die, can someone help me out?
Create a "Health Pack" prefab from the editor. If you need more information about prefabs, the information is out there on the web. To create a prefab, simply drag and drop a GameObject from the scene to your project. Its name in the scene will become blue. You can delete it from the scene and it will still be in the project.
Drag the prefab from the project to the HealthPack slot in the inspector of your ennemy. The ennemy will now have a reference to the prefab.
When you want to create a new health pack, you can use the Object.Instantiate static method as specified by rutter. Here is the official doc. When you instantiate your new Health Pack, I guess you want it to appear where the ennemy is, wich means you'll want to use one of the method's overloads which takes a Vector3D position as a parameter, which will most likely be transform.position. Since those methods also ask for a Quaternion, just pass in the Quaternion.identity constant.
This is how your code could look:
if (randChance < percentDrop)
{
Object.Instantiate(HealthPack, transform.position, Quaternion.identity);
}
Another problem, as mentioned in my comment, is the Awake function: HealthPack = GetComponent<GameObject>();.
The HealthPack prefab should be assigned to the ennemy from the inspector. That line in the Awake function will assign your ennemy's GameObject component to HealthPack, which is not desirable in the current context.
I hope this helps!

Stuck trying to make the AI in Turn-Based Strategy Game

I can already make the movement grid via pathfinding and avoid obstacles for the player. Now I want to make the AI move itself based on the movement grid and available action points (just like the player does), but I don't know how to do it. Right now, I am only able to make the character move to the position (but it is not follow the pathfinding, this character suppose to be the AI). I am stuck trying to solve this problem, but couldn't. Could you guys help me out? Thanks.
Here is the code I've got so far (it makes the character which is suppose to be AI to move to the position, but it not follow the pathfinding):
using UnityEngine;
using System.Collections;
public class AIPlayer : Player
{
void Awake()
{
moveDestination = transform.position;
}
// Use this for initialization
void Start()
{
ColorChanger();
}
// Update is called once per frame
void Update()
{
}
public override void TurnUpdate()
{
if (GameManager.instance.currentPlayerIndex == 5)
{
if (Vector3.Distance(moveDestination, transform.position) > 0.1f)
{
transform.position += (moveDestination - transform.position).normalized * moveSpeed * Time.deltaTime;
if (Vector3.Distance(moveDestination, transform.position) <= 0.1f)
{
transform.position = moveDestination;
actionPoints--;
}
}
else
{
moveDestination = new Vector3(2 - Mathf.Floor(GameManager.instance.mapSize / 2), 1.5f, -2 + Mathf.Floor(GameManager.instance.mapSize / 2));
GameManager.instance.NextTurn();
}
}
base.TurnUpdate();
}
public override void TurnOnGUI()
{
}
public override void ColorChanger()
{
base.ColorChanger();
}
}
Here is the link video for the game:
http://www.youtube.com/watch?v=eo7DzbBPQBs&feature=youtu.be
There's no code for pathfinding there. It's just an overly complicated lerp. As well, moving directly to the position will cause major headaches with graphical obstacle avoidance.
Your best bet is to implement a grid-based navmesh and use something like an A* search to find the path. The movement would be limited to adjacent squares, so graphical obstacle avoidance wouldn't happen.
Have a look at this tutorial. It'll give you everything you need except for animating player movement and the game logic for the target position.

Categories