C# How do I get collision recognized between two objects - c#

Form1.cs
namespace SpaceInvadersV3
{
public partial class Form1 : Form
{
public bool isPressed;
Shooter player;
List<Missile> bullet;
List<Enemy> pirate;
Boundary bottom;
Boundary top;
Boundary left;
Boundary right;
public Form1()
{
InitializeComponent();
player = new Shooter(450,460);
bullet = new List<Missile>();
pirate = new List<Enemy>();
for (int i = 0; i < 10; i++)
{
Enemy temp = new Enemy();
pirate.Add(temp);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
player.Move();
foreach (Missile b in bullet)
{
b.Move();
}
foreach (Enemy p in pirate)
{
p.Move();
}
pictureBox1.Invalidate();
if (IsColliding(player, pirate) == true)
{
gameOver();
}
}
Error in "pirate" says that it cannot convert from 'System.Collections.Generic.List<SpaceInvadersV3.Enemy>' to 'SpaceInvadersV3.Enemy' I tried changing the 'IsColliding' function below from (Enemy b) to (List<Enemy> b) but then it doesn't recognize b.Bottom and says that List<Enemy> does not contain a definition for Bottom.
// Keybinds
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.A)
{
player.goleft = true;
}
if (e.KeyCode == Keys.D)
{
player.goright = true;
}
if (e.KeyCode == Keys.W)
{
player.goup = true;
}
if (e.KeyCode == Keys.S)
{
player.godown = true;
}
if (e.KeyCode == Keys.Space)
{
Missile temp = new Missile(player.x, player.y);
bullet.Add(temp);
}
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.A)
{
player.goleft = false;
}
if (e.KeyCode == Keys.D)
{
player.goright = false;
}
if (e.KeyCode == Keys.W)
{
player.goup = false;
}
if (e.KeyCode == Keys.S)
{
player.godown = false;
}
}
// keybinds
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
player.Draw(e.Graphics);
foreach (Missile b in bullet)
{
b.Draw(e.Graphics);
}
foreach (Enemy p in pirate)
{
p.Draw(e.Graphics);
}
}
private bool IsColliding(Shooter a, Enemy b)
{
bool colliding = true; // presume collision
if (a.Top() > b.Bottom())
{
colliding = false;
}
return colliding;
}
private void gameOver()
{
timer1.Stop();
MessageBox.Show("you died");
}
}
}
Box.cs where both Enemy and Shooter classes inherit from
using System.Drawing;
namespace SpaceInvadersV3
{
class Box
{
public Image pic;
public float x;
public float y;
public float speed;
public Box()
{
x = 0;
y = 0;
speed = 0;
}
// Image Resizing Code
public static Image resizeImage(Image imgToResize, Size size)
{
return (Image)(new Bitmap(imgToResize, size));
}
// image resizing code
public void Draw(Graphics g)
{
g.DrawImage(pic, x, y);
}
public float Width()
{
return pic.Width;
}
public float Height()
{
return pic.Height;
}
public float Left()
{
return x;
}
public float Right()
{
return x + Width();
}
public float Top()
{
return y;
}
public float Bottom()
{
return y + Height();
}
}
}
I Don't think if Shooter and Enemy classes are really relevant, but if you need them, I'll post them. Thanks for your help.

if (IsColliding(player, pirate) == true)
First of all, never write that. It looks amateurish to say "if it is true that these are colliding". Say "if these things are colliding":
if (IsColliding(player, pirate))
Similarly, prefer if (!whatever) to if (whatever == false).
Second, please use plural nouns for collections. That should be pirates, not pirate. You want to emphasize that there is a collection of them to the reader.
Error in "pirate" says that it cannot convert from 'List' to 'Enemy'
Your IsColliding takes a shooter and an enemy, but you are giving it a shooter and a list of enemies. IsColliding doesn't know how to deal with that.
You already know how to fix it. You wanted to move every enemy so you wrote:
foreach (Enemy p in pirate)
{
p.Move();
}
Now you want to check every enemy for collisions, so do the same thing:
foreach (Enemy p in pirate)
{
if (IsColliding(player, p)) { ... }
}
An advanced technique that you will eventually learn is to use query comprehensions on sequences:
var collisions = from p in pirate
where IsColliding(player, p)
select p;
foreach (Enemy p in collisions)
{
... handle the collision...
}
But learn to walk before you try to run.

Related

Unity change player PhotonNetwork Room with two object with collider

I'm looking for a solution of the following issue:
I have a player instantiated in lobby room at initial scene. There are two platform objects with colliders, I need to make one platform to join to one room with a scene and other platform to another room with another scene. I have attached the same script for both of platform with a boolean value which determines to which room to join. Instead of determine to which room to join it triggers both scripts. I need to work it in this way:
Platform A:
private bool teleportToShop = true;
If (teleportToShop) -> join shop room
Platform B:
private bool teleportToShop = false;
If (!teleportToShop) -> join event room
Here's my code attached to both game objects:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Portal : MonoBehaviourPunCallbacks
{
[SerializeField] private bool teleportToShop;
private float portalTime = 3f;
private string EVENT_HALL_TAG = "Cinema Hall";
private string LOBBY_TAG = "Lobby";
private string SHOP_TAG = "Shop";
private int currentRoom = 0;
private string nextRoom;
private PhotonView portalView;
private void Awake()
{
portalView = GetComponent<PhotonView>();
}
private void OnTriggerStay(Collider other)
{
if (portalView.IsMine)
{
if (other.GetComponent<PhotonView>().IsMine)
{
if (other.gameObject.tag == "Player")
{
if (portalTime > 0)
{
portalTime -= Time.deltaTime;
}
else
{
portalTime = 3f;
if (SceneManager.GetActiveScene().name == EVENT_HALL_TAG || SceneManager.GetActiveScene().name == SHOP_TAG)
{
currentRoom = 1;
PhotonNetwork.LeaveRoom();
}
else
{
currentRoom = 0;
PhotonNetwork.LeaveRoom();
}
}
}
}
}
}
private void OnTriggerExit(Collider other)
{
portalTime = 3f;
}
public override void OnConnectedToMaster()
{
PhotonNetwork.AutomaticallySyncScene = false;
PhotonNetwork.JoinLobby();
}
public override void OnJoinedLobby()
{
if (currentRoom == 0)
{
if (!teleportToShop)
{
PhotonNetwork.JoinRoom("EventHallRoom");
}
else if (teleportToShop)
{
PhotonNetwork.JoinRoom("ShopRoom");
}
}
else PhotonNetwork.JoinRoom("LobbyRoom");
}
public override void OnJoinRoomFailed(short returnCode, string message)
{
base.OnJoinRandomFailed(returnCode, message);
if (currentRoom == 0)
{
if (!teleportToShop)
{
PhotonNetwork.CreateRoom("EventHallRoom");
}
else if (teleportToShop)
{
PhotonNetwork.CreateRoom("ShopRoom");
}
}
else PhotonNetwork.CreateRoom("LobbyRoom");
}
public override void OnJoinedRoom()
{
if (currentRoom == 0)
{
if (!teleportToShop)
{
PhotonNetwork.LoadLevel(EVENT_HALL_TAG);
}
else if (teleportToShop)
{
PhotonNetwork.LoadLevel(SHOP_TAG);
}
}
else PhotonNetwork.LoadLevel(LOBBY_TAG);
}
public override void OnLeftRoom()
{
GameManager.currentPlayer = null;
}
}

My spawning in script is not working and I am unsure as to why this is happening [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
How my spawning in script should work is there is a large cube (250 by 250 by 250) and it has a box collider with the trigger enabled. Each mob has a value which is their health/10. My goal is to make it so that each area has a value of 100 and if it has less than that it will randomly spawn in a new mob until it goes back to 100 value. I am getting an error on the line that I am instantiating the mob on that it is giving a null reference exception error. I have assigned the enemy gameobjects in the instpector. I am purposfully not spawning in the spiders because I am doing something special for them. If there is any code you need just comment and I should be able to give it to you. Thank you
Edit: I also got an null reference exception error on start on the line where I am adding the Alk to the Enemies list
Edit: In this scene there are no other objects that would interfere with the spawning in because I disabled all of the other objects one by one and I got no errors. All of the values in the enemy base script that are related to this have values that have been assigned to them. I hope that helps narrow it down
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnInScript : MonoBehaviour
{
public class EnemyWorth
{
public float health;
public int weight;
public GameObject self;
public EnemyWorth(float health, int weight, GameObject self)
{
this.health = health;
this.weight = weight;
this.self = self;
}
}
public GameObject Alk;
public GameObject GoblinSpawn;
public GameObject Goblin;
public GameObject Cobra;
public GameObject Spider;
public GameObject SpiderMini;
[SerializeField]
public EnemyWorth[] Enemies;
public int areaWorth;
private int rand;
private float randX;
private float randY;
private float randZ;
// Start is called before the first frame update
void Start()
{
Enemies[0] = new EnemyWorth (Alk.GetComponent<EnemyBaseScript>().health, Alk.GetComponent<EnemyBaseScript>().worth, Alk);
Enemies[1] = new EnemyWorth (GoblinSpawn.GetComponent<EnemyBaseScript>().health, GoblinSpawn.GetComponent<EnemyBaseScript>().worth, GoblinSpawn);
Enemies[2] = new EnemyWorth (Goblin.GetComponent<EnemyBaseScript>().health, Goblin.GetComponent<EnemyBaseScript>().worth, Goblin);
Enemies[3] = new EnemyWorth (Cobra.GetComponent<EnemyBaseScript>().health, Cobra.GetComponent<EnemyBaseScript>().worth, Cobra);
Enemies[4] = new EnemyWorth (Spider.GetComponent<EnemyBaseScript>().health, Spider.GetComponent<EnemyBaseScript>().worth, Spider);
Enemies[5] = new EnemyWorth (SpiderMini.GetComponent<EnemyBaseScript>().health, SpiderMini.GetComponent<EnemyBaseScript>().worth, SpiderMini);
}
// Update is called once per frame
void Update()
{
if (areaWorth > 100)
{
return;
}
if (areaWorth < 100)
{
rand = Random.Range(0, 3);
randX = Random.Range(-125, 125);
randY = Random.Range(-125, 125);
randZ = Random.Range(-125, 125);
Instantiate(Enemies[rand].self, new Vector3(this.transform.position.x -randX, this.transform.position.y - randY, this.transform.position.z - randZ), Quaternion.identity); // I am getting an error on this line
}
}
private void OnTriggerEnter(Collider col)
{
if (col.gameObject == Enemies[0].self)
{
areaWorth += Enemies[0].weight;
}
else if (col.gameObject == Enemies[1].self)
{
areaWorth += Enemies[1].weight;
}
else if (col.gameObject == Enemies[2].self)
{
areaWorth += Enemies[2].weight;
}
else if (col.gameObject == Enemies[3].self)
{
areaWorth += Enemies[3].weight;
}
else if (col.gameObject == Enemies[4].self)
{
areaWorth += Enemies[4].weight;
}
else if (col.gameObject == Enemies[5].self)
{
areaWorth += Enemies[5].weight;
}
}
private void OnTriggerExit(Collider col)
{
if (col.gameObject == Enemies[0].self)
{
areaWorth += Enemies[0].weight;
}
else if (col.gameObject == Enemies[1].self)
{
areaWorth += Enemies[1].weight;
}
else if (col.gameObject == Enemies[2].self)
{
areaWorth += Enemies[2].weight;
}
else if (col.gameObject == Enemies[3].self)
{
areaWorth += Enemies[3].weight;
}
else if (col.gameObject == Enemies[4].self)
{
areaWorth += Enemies[4].weight;
}
else if (col.gameObject == Enemies[5].self)
{
areaWorth += Enemies[5].weight;
}
}
}
I realized that when enemies were spawning in the area value wouldnt go back up becuase there wasnt anything adding to the value when they spawned in. I also optimized the code a bit more.
I was able to fix it by doing this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnInScript : MonoBehaviour
{
[System.Serializable]
public class EnemyWorth
{
public int weight;
public GameObject self;
public EnemyWorth(int weight, GameObject self)
{
this.weight = weight;
this.self = self;
}
}
public GameObject[] monsters;
public EnemyWorth[] enemies = new EnemyWorth[6];
public int maxAreaWorth;
public float dimX;
public float dimY;
public float dimZ;
[SerializeField]
private int areaWorth;
private int rand;
private float randX;
private float randY;
private float randZ;
// Start is called before the first frame update
void Start()
{
for (int i = 0; i < monsters.Length; i++)
{
enemies[i] = new EnemyWorth(monsters[i].GetComponent<EnemyBaseScript>().worth, monsters[i]);
}
}
// Update is called once per frame
void Update()
{
if (areaWorth < maxAreaWorth)
{
rand = Random.Range(0, 3);
randX = Random.Range(-dimX, dimX);
randY = Random.Range(-dimY, dimY);
randZ = Random.Range(-dimZ, dimZ);
Instantiate(enemies[rand].self, new Vector3(this.transform.position.x -randX, this.transform.position.y - randY, this.transform.position.z - randZ), Quaternion.identity);
areaWorth += enemies[rand].weight;
}
}
private void OnTriggerEnter(Collider col)
{
if (col.gameObject == enemies[0].self)
{
areaWorth += enemies[0].weight;
}
else if (col.gameObject == enemies[1].self)
{
areaWorth += enemies[1].weight;
}
else if (col.gameObject == enemies[2].self)
{
areaWorth += enemies[2].weight;
}
else if (col.gameObject == enemies[3].self)
{
areaWorth += enemies[3].weight;
}
else if (col.gameObject == enemies[4].self)
{
areaWorth += enemies[4].weight;
}
else if (col.gameObject == enemies[5].self)
{
areaWorth += enemies[5].weight;
}
}
private void OnTriggerExit(Collider col)
{
if (col.gameObject == enemies[0].self)
{
areaWorth += enemies[0].weight;
}
else if (col.gameObject == enemies[1].self)
{
areaWorth += enemies[1].weight;
}
else if (col.gameObject == enemies[2].self)
{
areaWorth += enemies[2].weight;
}
else if (col.gameObject == enemies[3].self)
{
areaWorth += enemies[3].weight;
}
else if (col.gameObject == enemies[4].self)
{
areaWorth += enemies[4].weight;
}
else if (col.gameObject == enemies[5].self)
{
areaWorth += enemies[5].weight;
}
}
}

Snake. Roll back the coordinates of the snake to impact

I can’t realize the possibility of continuing the game after a collision. The snake should stop and start moving after clicking on one of the arrow buttons.
In a collision, a window appears about the loss, I need to continue the game.
I press the button and the following happens:
I don’t understand how I can save the coordinates of the snake just before the collision.
In the moveTimer_Tick method, all elements move, i.e. new coordinates have already appeared at the head and body, then there is a check for collisions with the wall and body. If they are found, a window appears about the loss.
New snake coordinates are not displayed. But after clicking the "Continue" button, an update occurs and the snake climbs to the border.
The question is: how can I save the coordinates of the snake, before the collision, and after continuing to start with them.
namespace Snake{
public partial class MainWindow : Window
{
//The field on which the snake lives
Entity field;
// snake head
Head head;
// whole snake
List<PositionedEntity> snake;
// apple
Apple apple;
//number of points
int score;
// Is movement paused
bool paused;
//time
DispatcherTimer moveTimer;
//constructor form
public MainWindow()
{
InitializeComponent();
snake = new List<PositionedEntity>();
//create field 600x600pixels
field = new Entity(600, 600, "pack://application:,,,/Resources/snake.png");
//create a timer that runs every 300 ms
moveTimer = new DispatcherTimer();
moveTimer.Interval = new TimeSpan(0, 0, 0, 0, 300);
moveTimer.Tick += new EventHandler(moveTimer_Tick);
}
//redraw screen method
private void UpdateField()
{
//update the position of the elements of the snake
foreach (var p in snake)
{
Canvas.SetTop(p.image, p.y);
Canvas.SetLeft(p.image, p.x);
}
//update the position of apple
Canvas.SetTop(apple.image, apple.y);
Canvas.SetLeft(apple.image, apple.x);
//points update
lblScore.Content = String.Format("{0}000", score);
}
//timer tick handler. All movement takes place here.
void moveTimer_Tick(object sender, EventArgs e)
{
// Do not update if movement is paused
if(paused) {
return;
}
//in the reverse order we move all the elements of the snake
foreach (var p in Enumerable.Reverse(snake))
{
p.move();
}
//we check that the head of the snake did not crash into the body
foreach (var p in snake.Where(x => x != head))
{
if (p.x == head.x && p.y == head.y)
{
//we lose
moveTimer.Stop();
GameOver.Visibility = Visibility.Visible;
btnRestart.Visibility = Visibility.Visible;
tbScore.Text = String.Format("SCORE: {0}000", score);
return;
}
}
//check that the head of the snake did not go out of the field
if (head.x < 40 || head.x >= 540 || head.y < 40 || head.y >= 540)
{
//we lose
moveTimer.Stop();
GameOver.Visibility = Visibility.Visible;
btnRestart.Visibility = Visibility.Visible;
tbScore.Text = String.Format("SCORE: {0}000", score);
return;
}
//check that the head of the snake crashed into an apple
if (head.x == apple.x && head.y == apple.y)
{
//increase the score
score++;
//move the apple to a new place
apple.move();
var part = new BodyPart(snake.Last());
canvas1.Children.Add(part.image);
snake.Add(part);
}
UpdateField();
}
private void Window_KeyDown(object sender, KeyEventArgs e)
{
// Unpause movement when any key is pressed
if(paused) {
paused = false;
}
switch (e.Key)
{
case Key.Up:
head.direction = Head.Direction.UP;
break;
case Key.Down:
head.direction = Head.Direction.DOWN;
break;
case Key.Left:
head.direction = Head.Direction.LEFT;
break;
case Key.Right:
head.direction = Head.Direction.RIGHT;
break;
}
}
// "Start"
private void button1_Click(object sender, RoutedEventArgs e)
{
btnStart.Visibility = Visibility.Hidden;
btnRestart.Visibility = Visibility.Hidden;
tBNotEnoughPoints.Visibility = Visibility.Hidden;
score = 0;
snake.Clear();
canvas1.Children.Clear();
// "Game Over"
GameOver.Visibility = Visibility.Hidden;
canvas1.Children.Add(field.image);
apple = new Apple(snake);
canvas1.Children.Add(apple.image);
head = new Head();
snake.Add(head);
canvas1.Children.Add(head.image);
moveTimer.Start();
UpdateField();
}
private void btnContinue_Click(object sender, RoutedEventArgs e)
{
if (score >= 2)
{
GameOver.Visibility = Visibility.Hidden;
btnRestart.Visibility = Visibility.Hidden;
score -= 2;
// Pause movement
paused = true;
moveTimer.Start();
UpdateField();
}
else
{
tBNotEnoughPoints.Visibility = Visibility.Visible;
}
}
public class Entity
{
protected int m_width;
protected int m_height;
Image m_image;
public Entity(int w, int h, string image)
{
m_width = w;
m_height = h;
m_image = new Image();
m_image.Source = (new ImageSourceConverter()).ConvertFromString(image) as ImageSource;
m_image.Width = w;
m_image.Height = h;
}
public Image image
{
get
{
return m_image;
}
}
}
public class PositionedEntity : Entity
{
protected int m_x;
protected int m_y;
public PositionedEntity(int x, int y, int w, int h, string image)
: base(w, h, image)
{
m_x = x;
m_y = y;
}
public virtual void move() { }
public int x
{
get
{
return m_x;
}
set
{
m_x = value;
}
}
public int y
{
get
{
return m_y;
}
set
{
m_y = value;
}
}
}
public class Apple : PositionedEntity
{
List<PositionedEntity> m_snake;
public Apple(List<PositionedEntity> s)
: base(0, 0, 40, 40, "pack://application:,,,/Resources/fruit.png")
{
m_snake = s;
move();
}
public override void move()
{
Random rand = new Random();
do
{
x = rand.Next(13) * 40 + 40 ;
y = rand.Next(13) * 40 + 40 ;
bool overlap = false;
foreach (var p in m_snake)
{
if (p.x == x && p.y == y)
{
overlap = true;
break;
}
}
if (!overlap)
break;
} while (true);
}
}
public class Head : PositionedEntity
{
public enum Direction
{
RIGHT, DOWN, LEFT, UP, NONE
};
Direction m_direction;
public Direction direction {
set
{
m_direction = value;
RotateTransform rotateTransform = new RotateTransform(90 * (int)value);
image.RenderTransform = rotateTransform;
}
}
public Head()
: base(280, 280, 40, 40, "pack://application:,,,/Resources/head.png")
{
image.RenderTransformOrigin = new Point(0.5, 0.5);
m_direction = Direction.NONE;
}
public override void move()
{
switch (m_direction)
{
case Direction.DOWN:
y += 40;
break;
case Direction.UP:
y -= 40;
break;
case Direction.LEFT:
x -= 40;
break;
case Direction.RIGHT:
x += 40;
break;
}
}
}
public class BodyPart : PositionedEntity
{
PositionedEntity m_next;
public BodyPart(PositionedEntity next)
: base(next.x, next.y, 40, 40, "pack://application:,,,/Resources/body.png")
{
m_next = next;
}
public override void move()
{
x = m_next.x;
y = m_next.y;
}
}
}
}
There is something to say about the design of your code, but if you don't care and you want a fast (and ugly) solution you can modify your PositionEntity in order to store old coordinates:
public class PositionedEntity : Entity
{
protected int m_x;
protected int m_y;
protected int m_oldX;
protected int m_oldY;
public PositionedEntity(int x, int y, int w, int h, string image)
: base(w, h, image)
{
m_x = x;
m_y = y;
m_oldX = x;
m_oldY = y;
}
public virtual void move() { }
public virtual void RestorePrevious()
{
m_x = m_oldX;
m_y = m_oldY;
}
public int x
{
get
{
return m_x;
}
set
{
m_oldX = m_x;
m_x = value;
}
}
public int y
{
get
{
return m_y;
}
set
{
m_oldY = m_y;
m_y = value;
}
}
}
When you have a collision you should call the RestorePrevious() on the head and on all the rest of the snake

UNITY3D c# Teleport object on certain amount of points

I encountered a problem with this code. The "Killer" teleports to the location and immediately goes back to the starting position. I have 7 locations for the "Killer" to teleport to (around the player). Whats wrong with this code? (I am a newbie) If possible could you add a sound to every point collected? example. When I get 1 points a sound/audio file plays. Thanks for answers!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FpsScoreScript : MonoBehaviour
{
public int points;
bool isTeleported1 = false;
bool isTeleported2 = false;
bool isTeleported3 = false;
bool isTeleported4 = false;
bool isTeleported5 = false;
bool isTeleported6 = false;
bool isTeleported7 = false;
bool isTeleported8 = false;
public GameObject Killer;
public GameObject Player;
public Transform Destination;
public Transform KillerDestFarBack;
public Transform KillerDestCloseBack;
public Transform KillerDestRight;
public Transform KillerDestLeft;
public Transform KillerDestRightFront;
public Transform KillerDestLeftFront;
public Transform KillerDestFront;
public void Update()
{
if (points == 1 && !isTeleported1)
{
Teleport1();
}
if (points == 2 && !isTeleported2)
{
Teleport2();
}
if (points == 3 && !isTeleported3)
{
Teleport3();
}
if (points == 4 && !isTeleported4)
{
Teleport4();
}
if (points == 5 && !isTeleported5)
{
Teleport5();
}
if (points == 6 && !isTeleported6)
{
Teleport6();
}
if (points == 7 && !isTeleported7)
{
Teleport7();
}
if (points == 8 && !isTeleported8)
{
Teleport8();
}
}
void Teleport1()
{
isTeleported1 = true;
Killer.transform.position = KillerDestFront.transform.position;
}
void Teleport2()
{
isTeleported2 = true;
Killer.transform.position = KillerDestRightFront.transform.position;
}
void Teleport3()
{
isTeleported3 = true;
Killer.transform.position = KillerDestLeftFront.transform.position;
}
void Teleport4()
{
isTeleported4 = true;
Killer.transform.position = KillerDestRight.transform.position;
}
void Teleport5()
{
isTeleported5 = true;
Killer.transform.position = KillerDestLeft.transform.position;
}
void Teleport6()
{
isTeleported6 = true;
Killer.transform.position = KillerDestFarBack.transform.position;
}
void Teleport7()
{
isTeleported7 = true;
Killer.transform.position = KillerDestCloseBack.transform.position;
}
void Teleport8()
{
isTeleported8 = true;
Player.transform.position = Destination.transform.position;
}
}
Instead of using many Transform vars, I would prefer using a transform array, also I have used an array of bools has teleported. I would prefer you to follow some tutorials or get a book. Add a collider to your player and the coin.
[SerializeField] Transform[] teleportPoints;
[SerializeField]Transform coin;
bool[] hasTeleported;
AudioSource source;
int points = 0 ;
void Awake()
{
source = GetComponent<AudioSource>();
hasTeleported = new bool[teleportPoints.Length];
}
private void Update()
{
for(int i = 0; i <= teleportPoints.Length; i++)
{
if (points == i && !hasTeleported[i])
{
Teleport(i);
}
}
}
void Teleport(int index)
{
transform.position = teleportPoints[index].position;
hasTeleported[index] = true;
}
void IncreasePoints()
{
source.Play();
points++;
}
private void OnCollisionEnter(Collision collision)
{
if(collision.gameObject == coin.gameObject)
{
IncreasePoints();
}
}

Unity HTC VIVE Teleportation

I am developing for the HTC VIVE and am trying to create a teleportation script that would allow the user to teleport to a certain location (predefined by me) when the user grabs a certain object. I currently have a teleportation code that works like a normal teleporter where the user points at a location and the room is moved to that location. I have modified this so that no matter where the user is pointing they will always teleport to the specific location. This is a first step but I am really looking to trigger this teleportation when the user picks up a certain object, does anyone have any ideas on where to star or how to do this?
Here is the code for the modified teleporter:
namespace VRTK{
using UnityEngine;
using System.Collections;
public delegate void TeleportEventHandler(object sender, DestinationMarkerEventArgs e);
public class VRTK_BasicTeleport : MonoBehaviour
{
public float blinkTransitionSpeed = 0.6f;
[Range(0f, 32f)]
public float distanceBlinkDelay = 0f;
public bool headsetPositionCompensation = true;
public string ignoreTargetWithTagOrClass;
public bool limitToNavMesh = false;
public event TeleportEventHandler Teleporting;
public event TeleportEventHandler Teleported;
protected Transform eyeCamera;
protected bool adjustYForTerrain = false;
protected bool enableTeleport = true;
private float blinkPause = 0f;
private float fadeInTime = 0f;
private float maxBlinkTransitionSpeed = 1.5f;
private float maxBlinkDistance = 33f;
public void InitDestinationSetListener(GameObject markerMaker)
{
if (markerMaker)
{
foreach (var worldMarker in markerMaker.GetComponents<VRTK_DestinationMarker>())
{
worldMarker.DestinationMarkerSet += new DestinationMarkerEventHandler(DoTeleport);
worldMarker.SetInvalidTarget(ignoreTargetWithTagOrClass);
worldMarker.SetNavMeshCheck(limitToNavMesh);
worldMarker.SetHeadsetPositionCompensation(headsetPositionCompensation);
}
}
}
protected virtual void Start()
{
Utilities.SetPlayerObject(this.gameObject, VRTK_PlayerObject.ObjectTypes.CameraRig);
adjustYForTerrain = false;
eyeCamera = Utilities.AddCameraFade();
InitDestinationMarkerListeners();
InitHeadsetCollisionListener();
enableTeleport = true;
}
protected void OnTeleporting(object sender, DestinationMarkerEventArgs e)
{
if (Teleporting != null)
Teleporting(this, e);
}
protected void OnTeleported(object sender, DestinationMarkerEventArgs e)
{
if (Teleported != null)
Teleported(this, e);
}
protected virtual void Blink(float transitionSpeed)
{
fadeInTime = transitionSpeed;
SteamVR_Fade.Start(Color.black, 0);
Invoke("ReleaseBlink", blinkPause);
}
protected virtual bool ValidLocation(Transform target)
{
//If the target is one of the player objects or a UI Canvas then it's never a valid location
if(target.GetComponent<VRTK_PlayerObject>() || target.GetComponent<VRTK_UIGraphicRaycaster>())
{
return false;
}
bool validNavMeshLocation = false;
if (target)
{
NavMeshHit hit;
validNavMeshLocation = NavMesh.SamplePosition(target.position, out hit, 1.0f, NavMesh.AllAreas);
}
if (!limitToNavMesh)
{
validNavMeshLocation = true;
}
return (validNavMeshLocation && target && target.tag != ignoreTargetWithTagOrClass && target.GetComponent(ignoreTargetWithTagOrClass) == null);
}
protected virtual void DoTeleport(object sender, DestinationMarkerEventArgs e)
{
if (enableTeleport && ValidLocation(e.target) && e.enableTeleport)
{
OnTeleporting(sender, e);
Vector3 newPosition = GetNewPosition(e.destinationPosition, e.target);
CalculateBlinkDelay(blinkTransitionSpeed, newPosition);
Blink(blinkTransitionSpeed);
SetNewPosition(newPosition, e.target);
OnTeleported(sender, e);
}
}
protected virtual void SetNewPosition(Vector3 position, Transform target)
{
this.transform.position = CheckTerrainCollision(position, target);
}
protected virtual Vector3 GetNewPosition(Vector3 tipPosition, Transform target)
{
float newX = 0;
float newY = 17;
float newZ = 0;
return new Vector3(newX, newY, newZ);
}
protected Vector3 CheckTerrainCollision(Vector3 position, Transform target)
{
if (adjustYForTerrain && target.GetComponent<Terrain>())
{
var terrainHeight = Terrain.activeTerrain.SampleHeight(position);
position.y = (terrainHeight > position.y ? position.y : terrainHeight);
}
return position;
}
private void CalculateBlinkDelay(float blinkSpeed, Vector3 newPosition)
{
blinkPause = 0f;
if (distanceBlinkDelay > 0f)
{
float distance = Vector3.Distance(this.transform.position, newPosition);
blinkPause = Mathf.Clamp((distance * blinkTransitionSpeed) / (maxBlinkDistance - distanceBlinkDelay), 0, maxBlinkTransitionSpeed);
blinkPause = (blinkSpeed <= 0.25 ? 0f : blinkPause);
}
}
private void ReleaseBlink()
{
SteamVR_Fade.Start(Color.clear, fadeInTime);
fadeInTime = 0f;
}
private void InitDestinationMarkerListeners()
{
var controllerManager = GameObject.FindObjectOfType<SteamVR_ControllerManager>();
InitDestinationSetListener(controllerManager.left);
InitDestinationSetListener(controllerManager.right);
foreach (var destinationMarker in GameObject.FindObjectsOfType<VRTK_DestinationMarker>())
{
if (destinationMarker.gameObject != controllerManager.left && destinationMarker.gameObject != controllerManager.right)
{
InitDestinationSetListener(destinationMarker.gameObject);
}
}
}
private void InitHeadsetCollisionListener()
{
var headset = GameObject.FindObjectOfType<VRTK_HeadsetCollisionFade>();
if (headset)
{
headset.HeadsetCollisionDetect += new HeadsetCollisionEventHandler(DisableTeleport);
headset.HeadsetCollisionEnded += new HeadsetCollisionEventHandler(EnableTeleport);
}
}
private void DisableTeleport(object sender, HeadsetCollisionEventArgs e)
{
enableTeleport = false;
}
private void EnableTeleport(object sender, HeadsetCollisionEventArgs e)
{
enableTeleport = true;
}
}
And here is the code for the pointer:
namespace VRTK{
using UnityEngine;
using System.Collections;
public class VRTK_BezierPointer : VRTK_WorldPointer
{
public float pointerLength = 10f;
public int pointerDensity = 10;
public bool showPointerCursor = true;
public float pointerCursorRadius = 0.5f;
public float beamCurveOffset = 1f;
public GameObject customPointerTracer;
public GameObject customPointerCursor;
public LayerMask layersToIgnore = Physics.IgnoreRaycastLayer;
private GameObject projectedBeamContainer;
private GameObject projectedBeamForward;
private GameObject projectedBeamJoint;
private GameObject projectedBeamDown;
private GameObject pointerCursor;
private GameObject curvedBeamContainer;
private CurveGenerator curvedBeam;
// Use this for initialization
protected override void Start()
{
base.Start();
InitProjectedBeams();
InitPointer();
TogglePointer(false);
}
protected override void Update()
{
base.Update();
if (projectedBeamForward.gameObject.activeSelf)
{
ProjectForwardBeam();
ProjectDownBeam();
DisplayCurvedBeam();
SetPointerCursor();
}
}
protected override void InitPointer()
{
pointerCursor = (customPointerCursor ? Instantiate(customPointerCursor) : CreateCursor());
pointerCursor.name = string.Format("[{0}]WorldPointer_BezierPointer_PointerCursor", this.gameObject.name);
Utilities.SetPlayerObject(pointerCursor, VRTK_PlayerObject.ObjectTypes.Pointer);
pointerCursor.layer = LayerMask.NameToLayer("Ignore Raycast");
pointerCursor.SetActive(false);
curvedBeamContainer = new GameObject(string.Format("[{0}]WorldPointer_BezierPointer_CurvedBeamContainer", this.gameObject.name));
Utilities.SetPlayerObject(curvedBeamContainer, VRTK_PlayerObject.ObjectTypes.Pointer);
curvedBeamContainer.SetActive(false);
curvedBeam = curvedBeamContainer.gameObject.AddComponent<CurveGenerator>();
curvedBeam.transform.parent = null;
curvedBeam.Create(pointerDensity, pointerCursorRadius, customPointerTracer);
base.InitPointer();
}
protected override void SetPointerMaterial()
{
if (pointerCursor.GetComponent<Renderer>())
{
pointerCursor.GetComponent<Renderer>().material = pointerMaterial;
}
foreach (Renderer mr in pointerCursor.GetComponentsInChildren<Renderer>())
{
mr.material = pointerMaterial;
}
base.SetPointerMaterial();
}
protected override void TogglePointer(bool state)
{
state = (pointerVisibility == pointerVisibilityStates.Always_On ? true : state);
projectedBeamForward.gameObject.SetActive(state);
projectedBeamJoint.gameObject.SetActive(state);
projectedBeamDown.SetActive(state);
}
protected override void DisablePointerBeam(object sender, ControllerInteractionEventArgs e)
{
base.DisablePointerBeam(sender, e);
TogglePointerCursor(false);
curvedBeam.TogglePoints(false);
}
protected override void OnDestroy()
{
base.OnDestroy();
if (projectedBeamDown != null)
{
Destroy(projectedBeamDown);
}
if (pointerCursor != null)
{
Destroy(pointerCursor);
}
if (curvedBeam != null)
{
Destroy(curvedBeam);
}
if (projectedBeamContainer != null)
{
Destroy(projectedBeamContainer);
}
if (curvedBeamContainer != null)
{
Destroy(curvedBeamContainer);
}
}
private GameObject CreateCursor()
{
var cursorYOffset = 0.02f;
var cursor = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
cursor.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
cursor.GetComponent<MeshRenderer>().receiveShadows = false;
cursor.transform.localScale = new Vector3(pointerCursorRadius, cursorYOffset, pointerCursorRadius);
Destroy(cursor.GetComponent<CapsuleCollider>());
return cursor;
}
private void TogglePointerCursor(bool state)
{
var pointerCursorState = (showPointerCursor && state ? showPointerCursor : false);
var playAreaCursorState = (showPlayAreaCursor && state ? showPlayAreaCursor : false);
pointerCursor.gameObject.SetActive(pointerCursorState);
base.TogglePointer(playAreaCursorState);
}
private void InitProjectedBeams()
{
projectedBeamContainer = new GameObject(string.Format("[{0}]WorldPointer_BezierPointer_ProjectedBeamContainer", this.gameObject.name));
Utilities.SetPlayerObject(projectedBeamContainer, VRTK_PlayerObject.ObjectTypes.Pointer);
projectedBeamContainer.transform.parent = this.transform;
projectedBeamContainer.transform.localPosition = Vector3.zero;
projectedBeamForward = new GameObject(string.Format("[{0}]WorldPointer_BezierPointer_ProjectedBeamForward", this.gameObject.name));
Utilities.SetPlayerObject(projectedBeamForward, VRTK_PlayerObject.ObjectTypes.Pointer);
projectedBeamForward.transform.parent = projectedBeamContainer.transform;
projectedBeamJoint = new GameObject(string.Format("[{0}]WorldPointer_BezierPointer_ProjectedBeamJoint", this.gameObject.name));
Utilities.SetPlayerObject(projectedBeamJoint, VRTK_PlayerObject.ObjectTypes.Pointer);
projectedBeamJoint.transform.parent = projectedBeamContainer.transform;
projectedBeamJoint.transform.localScale = new Vector3(0.01f, 0.01f, 0.01f);
projectedBeamDown = new GameObject(string.Format("[{0}]WorldPointer_BezierPointer_ProjectedBeamDown", this.gameObject.name));
Utilities.SetPlayerObject(projectedBeamDown, VRTK_PlayerObject.ObjectTypes.Pointer);
}
private float GetForwardBeamLength()
{
var actualLength = pointerLength;
Ray pointerRaycast = new Ray(transform.position, transform.forward);
RaycastHit collidedWith;
var hasRayHit = Physics.Raycast(pointerRaycast, out collidedWith, pointerLength, ~layersToIgnore);
//reset if beam not hitting or hitting new target
if (!hasRayHit || (pointerContactTarget && pointerContactTarget != collidedWith.transform))
{
pointerContactDistance = 0f;
}
//check if beam has hit a new target
if (hasRayHit)
{
pointerContactDistance = collidedWith.distance;
}
//adjust beam length if something is blocking it
if (hasRayHit && pointerContactDistance < pointerLength)
{
actualLength = pointerContactDistance;
}
return actualLength;
}
private void ProjectForwardBeam()
{
var setThicknes = 0.01f;
var setLength = GetForwardBeamLength();
//if the additional decimal isn't added then the beam position glitches
var beamPosition = setLength / (2 + 0.00001f);
projectedBeamForward.transform.localScale = new Vector3(setThicknes, setThicknes, setLength);
projectedBeamForward.transform.localPosition = new Vector3(0f, 0f, beamPosition);
projectedBeamJoint.transform.localPosition = new Vector3(0f, 0f, setLength - (projectedBeamJoint.transform.localScale.z / 2));
projectedBeamContainer.transform.localRotation = Quaternion.identity;
}
private void ProjectDownBeam()
{
projectedBeamDown.transform.position = new Vector3(projectedBeamJoint.transform.position.x, projectedBeamJoint.transform.position.y, projectedBeamJoint.transform.position.z);
Ray projectedBeamDownRaycast = new Ray(projectedBeamDown.transform.position, Vector3.down);
RaycastHit collidedWith;
var downRayHit = Physics.Raycast(projectedBeamDownRaycast, out collidedWith, float.PositiveInfinity, ~layersToIgnore);
if (!downRayHit || (pointerContactTarget && pointerContactTarget != collidedWith.transform))
{
if (pointerContactTarget != null)
{
base.PointerOut();
}
pointerContactTarget = null;
destinationPosition = Vector3.zero;
}
if (downRayHit)
{
projectedBeamDown.transform.position = new Vector3(projectedBeamJoint.transform.position.x, projectedBeamJoint.transform.position.y - collidedWith.distance, projectedBeamJoint.transform.position.z);
projectedBeamDown.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
pointerContactTarget = collidedWith.transform;
destinationPosition = projectedBeamDown.transform.position;
base.PointerIn();
}
}
private void SetPointerCursor()
{
if (pointerContactTarget != null)
{
TogglePointerCursor(true);
pointerCursor.transform.position = projectedBeamDown.transform.position;
base.SetPlayAreaCursorTransform(pointerCursor.transform.position);
UpdatePointerMaterial(pointerHitColor);
}
else
{
TogglePointerCursor(false);
UpdatePointerMaterial(pointerMissColor);
}
}
private void DisplayCurvedBeam()
{
Vector3[] beamPoints = new Vector3[]
{
this.transform.position,
projectedBeamJoint.transform.position + new Vector3(0f, beamCurveOffset, 0f),
projectedBeamDown.transform.position,
projectedBeamDown.transform.position,
};
curvedBeam.SetPoints(beamPoints, pointerMaterial);
if (pointerVisibility != pointerVisibilityStates.Always_Off)
{
curvedBeam.TogglePoints(true);
}
}
}
}
How are you trying to pick the object. Do you use some sort of ray cast or just pick up on collision ? Nevertheless whatever you want to do triggering the teleportation when the object is picked up should be as simple as calling the teleport script from whatever script you using to pick up the object.
for eg:
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag ("Pick Up"))
{
<<call your teleport script here>>
}
}
Unity has really nice documentation for scripting and you can find a lot of tutorials that explain the basics, even if you go through one of them you should be able to do mostly anything you want with relative ease.

Categories