catch 22 regarding gameobject and OnMessage in unity/c# - c#

I am trying to catch a set of numbers from a websocket in unity and use it to update the orientation of a block. The problem is that if I tell it GameObject _cube = GameObject.Find("MyCube"); after void Start(), then OnMessage doesnt know what _cube is. If I try to use GameObject.Find in OnMessage, then it complains that find can only be used in the main thread.
I am not sure how to untangle this.
using UnityEngine;
using WebSocketSharp;
using WebSocketSharp.Server;
using System;
public class WS_Client : MonoBehaviour
{
public static GameObject _cube;
public class MyWebSocketServer : WebSocketBehavior
{
protected override void OnMessage(MessageEventArgs e)
{
string data = e.Data;
string[] components = data.Split(' ');
Debug.Log("splits components");
float x = float.Parse(components[0]);
float y = float.Parse(components[1]);
float z = float.Parse(components[2]);
Debug.Log("parses components");
Vector3 vector = new Vector3((float)x, (float)y, (float)z);
Debug.Log("puts them in vector3");
try
{
_cube.GetComponent<Transform>().eulerAngles = vector;
Debug.Log("rotates mycube");
//_cube.transform.eulerAngles = vector;
// _cube?.transform.eulerAngles = vector;
}
catch (Exception ex)
{
Debug.LogError("An error occurred: " + ex.Message);
}
}
protected override void OnOpen()
{
// Handle client connection here
Debug.Log("someone connected");
}
protected override void OnClose(CloseEventArgs e)
{
// Handle client disconnection here
Debug.Log("someone disconnected");
}
}
WebSocket ws;
[SerializeField] float speed = 50.0f;
// Start is called before the first frame update
void Start()
{
GameObject _cube = GameObject.Find("MyCube");
WebSocketServer wssv = new WebSocketServer(8080);
wssv.AddWebSocketService<MyWebSocketServer>("/MyWebSocket");
wssv.Start();
}
}

[SOLVED]
There is a slight race condition, but that is fine for my purposes. Basically the callback sends the data to the handle, and the handle just updates a local variable which is constantly being used in the main thread to transform my block.
using UnityEngine;
using WebSocketSharp;
using WebSocketSharp.Server;
using System;
public class OrientationEvent
{
public event Action<Vector3> OnOrientationUpdate;
}
public class WS_Client : MonoBehaviour
{
public static GameObject _cube;
private Action<Vector3> callback;
WebSocket ws;
[SerializeField] float speed = 50.0f;
private Vector3 _orientation;
// Start is called before the first frame update
void Start()
{
_cube = GameObject.Find("MyCube");
if (_cube == null)
{
Debug.Log("couldnt find MyCube at first");
}
WebSocketServer wssv = new WebSocketServer(8080);
Action<Vector3> callback = HandleOrientationUpdate;
MyWebSocketServer wsService = new MyWebSocketServer(callback);
wssv.AddWebSocketService<MyWebSocketServer>("/MyWebSocket", () => wsService);
wssv.Start();
}
public WS_Client(OrientationEvent orientationEvent)
{
callback = HandleOrientationUpdate;
}
private void Update()
{
_cube.transform.rotation = Quaternion.Euler(_orientation);
}
private void HandleOrientationUpdate(Vector3 orientation)
{
Debug.Log("tries to rotate mycube");
Debug.Log(orientation);
// Update the cube's orientation using the data from the event
try
{
_orientation = orientation;
Debug.Log("translates the orientation");
}
catch (Exception ex)
{
Debug.LogError("An error occurred: " + ex.Message);
}
}
}
public class MyWebSocketServer : WebSocketBehavior
{
private Action<Vector3> callback;
public MyWebSocketServer(Action<Vector3> callback)
{
this.callback = callback;
}
protected override void OnMessage(MessageEventArgs e)
{
string data = e.Data;
string[] components = data.Split(' ');
Debug.Log("splits components");
float x = float.Parse(components[0]);
float y = float.Parse(components[1]);
float z = float.Parse(components[2]);
Debug.Log("parses components");
Vector3 orientation = new Vector3(x, y, z);
// Vector3 vector = new Vector3((float)x, (float)y, (float)z);
Debug.Log("puts them in vector3");
try
{
callback?.Invoke(orientation);
Debug.Log("invokes action");
}
catch (Exception ex)
{
Debug.LogError("An error occurred: " + ex.Message);
}
}
protected override void OnOpen()
{
// Handle client connection here
Debug.Log("someone connected");
}
protected override void OnClose(CloseEventArgs e)
{
// Handle client disconnection here
Debug.Log("someone disconnected");
}
}

Related

Unity Ads. The ad loads, but when viewed, only the intro is shown and the ad is not shown further

I use Unity Ads and faced such a problem - test ads work fine in the editor (the page is shown), but I installed the build on my phone and ads do not work on it. More precisely, the ad is loaded and even at startup(but method OnUnityAdsShowStart isn't triggered), the intro of the unity ad is played (a circle with parts moving apart), but after that the black screen is on and OnUnityAdsShowFailure is triggered, sometimes it happens that, after waiting with a black screen, a test ad from Unity is played, but it still works OnUnityAdsShowFailure method.
This is my AdManager script.
using UnityEngine;
using UnityEngine.Advertisements;
using UnityEngine.UI;
public class AdManager : MonoBehaviour, IUnityAdsLoadListener, IUnityAdsShowListener
{
private string rewardedVideo = "Rewarded_Android";
private int with;
private int without;
[SerializeField]
private LevelSwitcher levelSwitcher;
[SerializeField]
private GameObject canvas;
[SerializeField]
private GameObject effect;
[SerializeField]
private Button[] buttons;
[SerializeField]
private Text adReady;
private bool isShowStart;
private void Awake()
{
with = 0;
without = 0;
adReady.text = "Ad is not loaded";
buttons[0].interactable = false;
buttons[1].interactable = false;
isShowStart = false;
}
public void Load()
{
Advertisement.Load(rewardedVideo, this);
Debug.Log("Loading Ad: " + rewardedVideo);
}
public void SetValue(int withAd, int withoutAd)
{
with = withAd;
without = withoutAd;
}
public void ShowVideo()
{
buttons[0].interactable = false;
buttons[1].interactable = false;
Advertisement.Show(rewardedVideo, this);
}
public void OnUnityAdsAdLoaded(string placementId)
{
Debug.Log("Ad Loaded: " + placementId);
if (placementId.Equals(rewardedVideo))
{
adReady.text = "Ad is loaded";
buttons[0].interactable = true;
buttons[1].interactable = true;
}
}
public void OnUnityAdsFailedToLoad(string placementId, UnityAdsLoadError error, string message)
{
Debug.Log($"Error loading Ad Unit {rewardedVideo}: {error.ToString()} - {message}");
adReady.text = "Ad is failed to load: " + error.ToString() + " " + message;
Advertisement.Load(rewardedVideo, this);
}
public void OnUnityAdsShowFailure(string placementId, UnityAdsShowError error, string message)
{
if (!isShowStart)
{
Debug.Log($"Show Failure: {error.ToString()} {message}");
adReady.text = "Ad is failed to show: " + error.ToString() + " " + message;
levelSwitcher.AddExperience(without);
GameObject instance = Instantiate(effect, new Vector3(transform.position.x, transform.position.y, 0.0f), Quaternion.identity, canvas.transform);
instance.GetComponent<RewardEffect>().SetText(without.ToString());
Time.timeScale = 1.0f;
Advertisement.Load(rewardedVideo, this);
}
}
public void OnUnityAdsShowStart(string placementId)
{
Debug.Log("Showing start");
isShowStart = true;
Time.timeScale = 0.0f;
}
public void OnUnityAdsShowClick(string placementId)
{
Debug.Log("Ad click");
}
public void OnUnityAdsShowComplete(string placementId, UnityAdsShowCompletionState showCompletionState)
{
if (placementId.Equals(rewardedVideo) && (showCompletionState.Equals(UnityAdsShowCompletionState.COMPLETED)))
{
Debug.Log("Unity Ads Rewarded Ad Completed Normaly");
levelSwitcher.AddExperience(with);
GameObject instance = Instantiate(effect, new Vector3(transform.position.x, transform.position.y, 0.0f), Quaternion.identity, canvas.transform);
instance.GetComponent<RewardEffect>().SetText(with.ToString());
Advertisement.Load(rewardedVideo, this);
}
else if(placementId.Equals(rewardedVideo))
{
Debug.Log("Unity Ads Rewarded Ad Completed Bad");
levelSwitcher.AddExperience(without);
GameObject instance = Instantiate(effect, new Vector3(transform.position.x, transform.position.y, 0.0f), Quaternion.identity, canvas.transform);
instance.GetComponent<RewardEffect>().SetText(without.ToString());
Advertisement.Load(rewardedVideo, this);
}
Time.timeScale = 1.0f;
isShowStart = false;
}
}
This is my ad initializing script
using UnityEngine;
using UnityEngine.Advertisements;
public class AdInitializer : MonoBehaviour, IUnityAdsInitializationListener
{
[SerializeField] string _androidGameId;
[SerializeField] string _iOSGameId;
[SerializeField] bool _testMode = true;
private string _gameId;
[SerializeField]
private AdManager adManager;
void Awake()
{
Initialize();
}
public void Initialize()
{
_gameId = (Application.platform == RuntimePlatform.IPhonePlayer)
? _iOSGameId
: _androidGameId;
Advertisement.Initialize(_gameId, _testMode, this);
}
public void OnInitializationComplete()
{
Debug.Log("Unity Ads initialization complete.");
adManager.Load();
}
public void OnInitializationFailed(UnityAdsInitializationError error, string message)
{
Debug.Log($"Unity Ads Initialization Failed: {error.ToString()} - {message}");
}
}
For the most part, I took the scripts from the official tutorial from the Unity, added only my own functionality.
I also tried to collect more information and in the logs when I start advertising, I get the following.
Everything that I found on the Internet did not help me, I hope there is someone who can help me or who has a similar problem.

Unity Photon.Pun Connecting isues When Change Scene

Hello Guys i am working on a small project and I installed the room setup system in the lobby without any problems, and when we set up the room, it directs us to a 2D scene. Everything was exactly what I wanted until now, like the room scene among us. LoadScene("Game"); I added the code and assigned it to the button. When I press the button, the scene changes, but [my status text says connecting but never connected, it's always stuck connecting and therefore players cannot go on stage] I'll share my codes below, can you help me?
Network.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using Photon.Pun;
using Photon.Realtime;
public class Network : MonoBehaviourPunCallbacks
{
public Text StatusText;
public CameraFollow playerCamera;
public MasterClient masterClient;
private void Start()
{
StatusText.text = "Connecting";
PhotonNetwork.NickName = "Player" + Random.Range(0, 5000);
// CreatePlayerCamera();
}
public void GameScene()
{
StatusText.text = "Joined " + PhotonNetwork.CurrentRoom.Name;
PhotonNetwork.LoadLevel("Game");
}
private void CreatePlayerCamera()
{
playerCamera.target = PhotonNetwork.Instantiate("Player", new Vector3(
Random.Range(-5, 5),
Random.Range(-5, 5),
0), Quaternion.identity).transform;
if (PhotonNetwork.IsMasterClient)
{
masterClient.Initialize();
}
}
public override void OnConnectedToMaster()
{
StatusText.text = "Connected to Master / Joining room";
PhotonNetwork.JoinOrCreateRoom("GameRoom", new RoomOptions() { MaxPlayers = 4 }, null);
CreatePlayerCamera();
}
public override void OnJoinedRoom ()
{
StatusText.text = PhotonNetwork.CurrentRoom.Name;
playerCamera.target = PhotonNetwork.Instantiate("Player",
new Vector3(
Random.Range(-10, 10),
Random.Range(-10, 10),
0), Quaternion.identity).transform;
}
}
Lobbynetwork.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine.UI;
public class LobbyNetworkManager : MonoBehaviourPunCallbacks
{
int number;
int number2;
public Text su;
private List<RoomItemUI> _roomList = new List<RoomItemUI> ();
[SerializeField] private RoomItemUI _roomItemUIPrefab;
[SerializeField] private Transform _roomListParent;
[SerializeField] private Text _statusField;
[SerializeField] private Button _leaveRoomButton;
[SerializeField] private InputField _roomInput;
[SerializeField] private InputField _joinInput;
[SerializeField] private RoomItemUI _playerItemUIPrefab;
[SerializeField] private Transform _playerListParent;
private List<RoomItemUI> _playerList = new List<RoomItemUI>();
private void Start()
{
Initialize();
Connect();
}
#region PhotonCallbacks
public override void OnConnectedToMaster()
{
Debug.Log("Connected to master server");
PhotonNetwork.JoinLobby();
}
public override void OnRoomListUpdate(List<RoomInfo> roomList)
{
UpdateRoomList(roomList);
}
public override void OnDisconnected(DisconnectCause cause)
{
Debug.Log("Disconnect");
}
public override void OnJoinedLobby()
{
Debug.Log("Joined Lobby!");
}
public override void OnJoinedRoom()
{
_statusField.text = "Joined " + PhotonNetwork.CurrentRoom.Name;
Debug.Log("Joined Room " + PhotonNetwork.CurrentRoom.Name);
MoveScene();
// _leaveRoomButton.interactable = true;
UpdatePlayerList();
}
private void MoveScene()
{
PhotonNetwork.LoadLevel("Room_Scene");
}
public override void OnLeftRoom()
{
_statusField.text = "Lobby";
Debug.Log("Left Room");
_leaveRoomButton.interactable = false;
UpdatePlayerList();
}
public override void OnPlayerEnteredRoom(Player newPlayer)
{
UpdatePlayerList();
}
public override void OnPlayerLeftRoom(Player otherPlayer)
{
UpdatePlayerList();
}
#endregion
private void Initialize()
{
_leaveRoomButton.interactable = false;
}
private void Connect()
{
PhotonNetwork.NickName = "Player" + Random.Range(0, 5000);
PhotonNetwork.ConnectUsingSettings();
PhotonNetwork.AutomaticallySyncScene = true;
}
private void UpdateRoomList(List<RoomInfo> roomList)
{
//Clear the current list of rooms
for (int i =0; i < _roomList.Count; i++)
{
Destroy(_roomList[i].gameObject);
}
_roomList.Clear();
// Generate a new list with the updated info
for (int i = 0; i < roomList.Count; i++)
{
//skip empty rooms
if(roomList[i].PlayerCount == 0) { continue; }
RoomItemUI newRoomItem = Instantiate(_roomItemUIPrefab);
newRoomItem.LobbyNetworkParent = this;
newRoomItem.SetName(roomList[i].Name);
newRoomItem.transform.SetParent(_roomListParent);
_roomList.Add(newRoomItem);
}
}
private void UpdatePlayerList()
{
//Clear the current player list
//clear current list of room
for (int i = 0; i < _playerList.Count; i++)
{
Destroy(_playerList[i].gameObject);
}
_playerList.Clear();
if(PhotonNetwork.CurrentRoom == null) { return; }
//Generate a new list of players
foreach(KeyValuePair<int, Player> player in PhotonNetwork.CurrentRoom.Players)
{
RoomItemUI newPlayerItem = Instantiate(_playerItemUIPrefab);
newPlayerItem.transform.SetParent(_playerListParent);
newPlayerItem.SetName(player.Value.NickName);
_playerList.Add(newPlayerItem);
}
}
public void JoinRoom(string roomName)
{
PhotonNetwork.JoinRoom(roomName);
}
public void CreateRoom()
{
number = Random.Range(1000, 9000);
number2 = Random.Range(100, 800);
PhotonNetwork.CreateRoom("Su" + number + "TR" + number2, new RoomOptions() { MaxPlayers = 4 }, null);
/* if (string.IsNullOrEmpty(_roomInput.text) == false)
{
PhotonNetwork.CreateRoom(_roomInput.text + number, new RoomOptions() { MaxPlayers = 4 }, null);
} */
MoveScene();
}
public void JoinWitchCode ()
{
PhotonNetwork.JoinRoom(_joinInput.text);
}
public void LeaveRoom()
{
PhotonNetwork.LeaveRoom();
}
}
Check my video
Youtube

Unity - Weird StackOverflow Exception thrown in output_log.txt after build

Today I'm coming to you because I have a weird StackOverflow Exception and do not know how to fix it at all...
First off, this seems to only happen on windows after I build the game.
This is what I see in the output_log.txt :
onMoneyChanged is being called! (4145)
UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
UnityEngine.Logger:Log(LogType, Object)
UnityEngine.Debug:Log(Object)
Player:set_Money(Int32) (at /Users/Name/Desktop/My Game/Assets/Scripts/Mobs/Player.cs:89)
Coin:OnPickup(ItemCollector) (at /Users/Name/Desktop/My Game/Assets/Scripts/Items/Coin.cs:12)
ItemCollector:Update() (at /Users/Name/Desktop/My Game/Assets/Scripts/Items/ItemCollector.cs:35)
(Filename: /Users/Name/Desktop/My Game/Assets/Scripts/Mobs/Player.cs Line: 89)
onMoneyChanged is being called! (4150)
UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
UnityEngine.Logger:Log(LogType, Object)
UnityEngine.Debug:Log(Object)
Player:set_Money(Int32) (at /Users/Name/Desktop/My Game/Assets/Scripts/Mobs/Player.cs:89)
Coin:OnPickup(ItemCollector) (at /Users/Name/Desktop/My Game/Assets/Scripts/Items/Coin.cs:12)
ItemCollector:Update() (at /Users/Name/Desktop/My Game/Assets/Scripts/Items/ItemCollector.cs:35)
(Filename: /Users/Name/Desktop/My Game/Assets/Scripts/Mobs/Player.cs Line: 89)
Uploading Crash Report
StackOverflowException: The requested operation caused a stack overflow.
at (wrapper delegate-invoke) System.Action:invoke_void__this__ ()
at (wrapper delegate-invoke) System.Action:invoke_void__this__ ()
at (wrapper delegate-invoke) System.Action:invoke_void__this__ ()
at (wrapper delegate-invoke) System.Action:invoke_void__this__ ()
at (wrapper delegate-invoke) System.Action:invoke_void__this__ ()
at (wrapper delegate-invoke) System.Action:invoke_void__this__ ()
at (wrapper delegate-invoke) System.Action:invoke_void__this__ ()
I have looked everywhere and can't seem to understand where it comes from. I might not be seeing something very simple...
Here is the player script:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Linq;
using UnityEngine;
using UnityEngine.Events;
using PixelUtilities;
public class Player : Mob, IUpgradable, IXmlSerializable {
#region Static Section
private static readonly AnimationParameter Skill2SpeedId = "Skill 2 Speed";
private static readonly string[] AttackAxisNames = new string[] {
null,
"Attack1",
"Attack2",
"Attack3"
};
//It seems this must be longer in duration than the transition into the attack state, due to the potential transition interruption sources!
private const float AttackUnjoggableTime = 0.65f;
#endregion
[Header("Player")]
[SerializeField] private float skill2Speed = 1;
[SerializeField] private Transform groundCheck;
[SerializeField] private float groundCheckRadius = 0.25f;
[SerializeField] private LayerMask groundLayers;
[SerializeField] private bool isGrounded;
[SerializeField] GameObject weaponSpecial;
private new Rigidbody2D rigidbody;
private new BoxCollider2D collider;
private float horizontal;
private float smoothedHorizontal;
private Vector3 velocity;
private int superCharge; //Represents the number of enemies defeated that counts towards allowing the player to use their super attack.
private bool canIncreaseSuperCharge = true;
private bool canSuperSmash;
private int money = 0;
//private int roundMoney = 0;
private int[] levels = new int[2];
//DO NOT show in the inspector. That will make it changeable without actually updating the data
//that needs to change based based on this upgradeLevel.
private int baseDamage;
private float timeLastAttacked;
public event Action onMoneyChanged;
public bool CanSuperSmash {
get { return canSuperSmash; }
set {
//Prevent from redundant setting, because we'll need to know
//just when the value changed from false to true
if (canSuperSmash == value)
return;
canSuperSmash = value;
weaponSpecial.SetActive(value);
if (value)
superCharge = GameManager.Mage.SpecialEnemyCount;
}
}
public BoxCollider2D Collider {
get { return collider; }
}
public int SuperCharge {
get { return superCharge; }
}
public int LevelCount {
get { return levels.Length; }
}
public int Money {
get { return money; }
set {
if (GameManager.IsDebugMode)
Debug.Log("Setting the player's money from " + money + " to " + value + ".");
money = value;
Debug.Log("onMoneyChanged is being called! (" + money + ")");
if (onMoneyChanged != null)
onMoneyChanged();
}
}
//public int RoundMoney {
// get { return roundMoney; }
// set {
// roundMoney = value;
// Debug.Log("roundMoney has been set to " + roundMoney + ".");
// }
//}
public override void Reset() {
base.Reset();
groundLayers = LayerMask.GetMask("Ground");
}
public override void Awake() {
base.Awake();
collider = GetComponentInChildren<BoxCollider2D>();
HPStatus.onDeath += OnDeath;
baseDamage = StandTallCurves.GetNthStepInEnemyHealthCurve(0) / 2;
}
public override void Start() {
rigidbody = GetComponent<Rigidbody2D>();
}
public int GetLevel(int levelIndex) {
return levels[levelIndex];
}
public void SetLevel(int levelIndex, int value) {
value = Mathf.Max(0, value);
levels[levelIndex] = value;
switch (levelIndex) {
case 0:
baseDamage = StandTallCurves.GetNthStepInEnemyHealthCurve(value) / 2;
break;
case 1:
HPStatus.HP = HPStatus.MaxHP = StandTallCurves.GetNthStepInEnemyHealthCurve(value);
break;
}
}
public override void StartAttack(int attackNumber) {
base.StartAttack(attackNumber);
timeLastAttacked = Time.time;
}
protected override void OnUpdate() {
isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayers);
if (CanPerformActions)
AcceptAttackInput();
AcceptMovementInput();
//AcceptJumpInput();
//AcceptRotationalInput();
if (GameManager.IsDeveloperMode) {
if (Input.GetKeyDown(KeyCode.C)) {
Money += 1000;
}
if (Input.GetKeyDown(KeyCode.Y)) {
CanSuperSmash = true;
}
if (Input.GetKeyDown(KeyCode.T) && (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.LeftCommand))) {
Time.timeScale = (Time.timeScale == 1) ? 5 : 1;
}
}
}
private void AcceptMovementInput() {
horizontal = hInput.GetAxis("Horizontal");
//smoothedHorizontal = Input.GetAxis("Horizontal");
velocity = rigidbody.velocity;
velocity.x = Mathf.Sign(horizontal) * FinalMovementSpeed;
rigidbody.velocity = velocity;
//Section for updating their rotation
if (horizontal < 0) {
Quaternion newRotation = transform.rotation;
newRotation.y = 180;
transform.rotation = newRotation;
}
if (horizontal > 0) {
Quaternion newRotation = transform.rotation;
newRotation.y = 0;
transform.rotation = newRotation;
}
}
private void AcceptAttackInput() {
for (int i = 1; i <= 2; i++) {
if (hInput.GetButtonDown(AttackAxisNames[i])) {
StartAttack(i);
return;
}
}
//Attack 3 is special for the player -- their super smash -- and is handled differently.
if (hInput.GetButtonDown(AttackAxisNames[3])) {
if (canSuperSmash) {
StartSuperSmash();
} else {
if (GameManager.IsDebugMode) {
Debug.Log("Attempted to super smash, but " + name + " was unable to super smash!");
}
}
}
}
protected override float CalculateFinalMovementSpeed() {
float finalMovementSpeed = Mathf.Abs(horizontal) * MoveSettings.MoveSpeed;
finalMovementSpeed *= MovementFactor;
return finalMovementSpeed;
}
protected override void UpdateContinuousAnimatorParameters() {
animator.SetBool(Animations.IsMovingId, Time.time - timeLastAttacked > AttackUnjoggableTime && Mathf.Abs(horizontal) > 0.08f && Mathf.Abs(velocity.x) > 0.08f);
//animator.SetFloat(Skill2SpeedId, skill2Speed);
}
/* Uncomment to enable jumping
private void AcceptJumpInput() {
if (Input.GetButtonDown("Jump") && isGrounded) {
rigidbody.velocity = new Vector3(rigidbody.velocity.x, JumpFactor * MoveSettings.JumpSpeed, 0);
if (JumpFactor > 0)
animator.SetTrigger(JumpId);
}
}*/
/// <summary>
/// This tells the whether or not the super charge count can be increased.
/// </summary>
public void SetSuperChargeActive(bool value) {
canIncreaseSuperCharge = value;
}
public bool GainSuperCharge() {
return GainSuperCharge(1);
}
public bool GainSuperCharge(int amount) {
//If they're already charged up, then don't allow superCharge to increment
if (!GameManager.Mage.gameObject.activeSelf || !canIncreaseSuperCharge || canSuperSmash)
return false;
superCharge = Mathf.Clamp(superCharge + amount, 0, GameManager.Mage.SpecialEnemyCount);
if (superCharge == GameManager.Mage.SpecialEnemyCount) {
CanSuperSmash = true; //Important to call the C# property here, NOT directly access the field, "canSuperSmash".
}
return true;
}
private void StartSuperSmash() {
SetSuperChargeActive(false);
CanSuperSmash = false;
StartCoroutine(AttackAfterDelay(3, 0)); //0 was initially 0.8f;
}
public void ClearSuperCharge() {
if (GameManager.IsDebugMode)
Debug.Log("superCharge set to 0!");
superCharge = 0;
}
private IEnumerator AttackAfterDelay(int attackNumber, float initialDelay) {
if (initialDelay > 0)
yield return new WaitForSeconds(initialDelay);
StartAttack(attackNumber);
}
public override void OnDrawGizmosSelected() {
base.OnDrawGizmosSelected();
if (groundCheck != null) {
Gizmos.color = new Color(0.6f, 1, 0, 1);
Gizmos.DrawWireSphere(groundCheck.position, groundCheckRadius);
}
attackChecker.DrawGizmos(Color.red);
}
private void InstantKillAllInView() {
Camera camera = Camera.main;
Vector3 cameraPos = camera.transform.position;
float height = 2 * camera.orthographicSize;
float width = height * camera.aspect; //h * (w/h) = w
RaycastHit2D[] hits = Physics2D.BoxCastAll((Vector2) cameraPos, new Vector2(width, height), 0, Vector2.right, 0.01f, enemyLayers, -0.01f, 0.01f);
for (int i = 0; i < hits.Length; i++) {
Mob target = hits[i].transform.GetComponent<Mob>();
if (target == null)
continue;
target.InstantSuperKill(this);
}
}
public void DamageOthersInRangeFromPlayer() {
DamageOthersInRange(baseDamage);
}
private void OnDeath(DamageInfo finalDamage) {
GameManager.StartGameOverScreen();
}
public void Load(XElement element) {
if (element == null)
return;
int intValue;
XElement child = element.Element("Money");
if (child != null && int.TryParse(child.Value, out intValue))
Money = intValue;
child = element.Element("HealthUpgrade");
if (child != null) {
//Old serialized layout
//if (int.TryParse(child.Value, out intValue))
// HealthUpgradeLevel = intValue;
//child = element.Element("DamageUpgrade");
//if (child != null && int.TryParse(child.Value, out intValue))
// DamageUpgradeLevel = intValue;
} else {
//New serialized layout
child = element.Element("Levels");
if (child != null)
LoadLevels(child, ref levels);
}
}
public XElement Save() {
XElement element = new XElement(GetType().Name);
element.Add(new XElement("Money", money));
//e.Add(new XElement("HealthUpgrade", healthUpgradeLevel));
//e.Add(new XElement("DamageUpgrade", damageUpgradeLevel));
element.Add(SaveLevels(ref levels));
return element;
}
#region Public Animator Methods
public void AnimatorAllowSuperSmashToRestart() {
ClearSuperCharge();
SetSuperChargeActive(true);
}
#endregion
}
Here is the Coin script:
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
public class Coin : MonoBehaviour, IItem {
[SerializeField] private int moneyAmount = 5;
public void OnValidate() {
moneyAmount = Mathf.Max(0, moneyAmount);
}
public void OnPickup(ItemCollector collector) {
collector.Owner.Money += moneyAmount;
//collector.Owner.RoundMoney += moneyAmount;
}
}
And finally, the itemCollector script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemCollector : MonoBehaviour {
[SerializeField] private float radius = 0.5f;
[SerializeField] private LayerMask itemMask;
private Player owner;
private Collider2D[] results = new Collider2D[16];
private int resultsCount;
public Player Owner {
get { return owner; }
}
public void Awake() {
owner = GetComponentInParent<Player>();
if (owner == null) {
if (GameManager.IsDebugMode) {
Debug.LogError(" require a " + typeof(Player).Name + " to be in a parent!" +
"\nThe " + GetType().Name + " will be destroyed, as it would not be able to function.");
}
DestroyImmediate(gameObject);
}
}
public void Update() {
resultsCount = Physics2D.OverlapCircleNonAlloc(transform.position, radius, results, itemMask);
for (int i = 0; i < resultsCount; i++) {
IItem item = results[i].GetComponent<IItem>();
if (item != null) {
MonoBehaviour m = item as MonoBehaviour;
if (m != null && m.enabled) {
item.OnPickup(this);
m.enabled = false;
GameObject.Destroy(m.gameObject);
}
}
}
}
public void OnDrawGizmosSelected() {
Gizmos.DrawWireSphere(transform.position, radius);
}
}
Thank you in advance for you help.
Regards!
For anyone who has a problem like that.
I fixed the problem. I had a .onMoneyChanged in an update function that was making the game crash.
I moved it to the onEnable and onDisable method and now it works just fine.

Coroutine not starting due to inactive game object

I'm getting an error message and I'm not exactly sure how to solve. I'm trying to start a countdown after a short period of idleness that then kicks off a second countdown that is paired with a visual warning. As soon as the coroutine kicks on I'm getting this error:
Coroutine couldn't be started because the the game object '_CountdownTimer' is inactive!
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
CountdownTimer:StartPreCountTimer() (at Assets/_Components/_Scripts/CountdownTimer.cs:38)
GameManager:CheckUserActivity() (at Assets/_Components/_Scripts/GameManager.cs:68)
What am I missing? Where would I need to set the active state of _CountdownTimer? Thank you!!
GameManager.cs
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public static GameManager gameManagerInstance = null; // Create Singleton
public float checkUserActivityInterval;
public GameObject loader;
public GameObject countdownTimer;
private GameObject gameManager;
private Vector3 currentMousePosition;
private Vector3 prevMousePosition;
private CountdownTimer countdownInstance;
private Scene currentScene;
public Color defaultBackgroundColor;
public Object startingScene;
public static bool userActive;
public static bool preCountActive;
public static bool restartWarningActive;
public static string animalDataFilePathJSON;
public static string animalDataFilePathTex;
void Awake ()
{
if (CountdownTimer.countdownTimerInstance == null)
Instantiate(countdownTimer);
if (gameManagerInstance == null)
gameManagerInstance = this;
else if (gameManagerInstance != null)
Destroy(gameObject);
DontDestroyOnLoad(gameObject);
}
void Start()
{
prevMousePosition = Input.mousePosition;
countdownInstance = countdownTimer.GetComponent<CountdownTimer>(); // Create an instance of CountdownTimer
InvokeRepeating("CheckUserActivity", 0, checkUserActivityInterval);
InvokeRepeating("SetPrevMousePosition", 0, checkUserActivityInterval);
}
void Update()
{
currentScene = SceneManager.GetActiveScene();
currentMousePosition = Input.mousePosition;
}
void CheckUserActivity()
{
if (currentScene.name != startingScene.name)
{
if (currentMousePosition == prevMousePosition)
{
Debug.Log("MOUSE HAS NOT MOVED!!");
userActive = false;
if (!userActive && !preCountActive)
countdownInstance.StartPreCountTimer();
}
if (currentMousePosition != prevMousePosition)
{
Debug.Log("MOUSE HAS MOVED!!");
userActive = true;
if (preCountActive == true)
countdownInstance.RestartPreCountTimer();
}
}
}
void SetPrevMousePosition()
{
prevMousePosition = Input.mousePosition;
}
}
CountdownTimer.cs
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class CountdownTimer : MonoBehaviour
{
public static CountdownTimer countdownTimerInstance = null; // Create Singleton
public Object startingScene;
public GameObject timeOutWarningDialog;
private GameObject timerDialogBoxInstance;
private GameObject canvas;
private IEnumerator counter;
private Button stopCountButton;
private Text timerTextField;
public float countdownLength;
public float countdownDelay;
private float countdownInterval = 1;
void Awake()
{
if (countdownTimerInstance == null)
countdownTimerInstance = this;
else if (countdownTimerInstance != null)
Destroy(gameObject);
DontDestroyOnLoad(gameObject);
}
public void StartPreCountTimer()
{
GameManager.preCountActive = true;
GameManager.restartWarningActive = false;
counter = RunTimer(countdownDelay); // create new reference to counter
StartCoroutine(counter);
}
public void RestartPreCountTimer()
{
GameManager.preCountActive = false;
StopTimer();
}
void ShowRestartWarning()
{
GameManager.preCountActive = false;
GameManager.restartWarningActive = true;
canvas = GameObject.FindGameObjectWithTag("Canvas");
timerDialogBoxInstance = Instantiate(timeOutWarningDialog); // instantiate timeout warning dialog
timerDialogBoxInstance.transform.SetParent(canvas.transform, false);
timerDialogBoxInstance.SetActive(true);
Text[] textFields = timerDialogBoxInstance.GetComponentsInChildren<Text>(true); // get reference to timer textfields
timerTextField = textFields[2]; // access and assign countdown textfield
stopCountButton = timerDialogBoxInstance.GetComponentInChildren<Button>(); // get reference to keep playing button
stopCountButton.onClick.AddListener(StopTimer); // add button listener
if (timerDialogBoxInstance.activeInHierarchy == true)
{
counter = RunTimer(countdownLength); // create new reference to counter, resets countdown to countdownLength
StartCoroutine(counter);
}
}
IEnumerator RunTimer(float seconds)
{
float s = seconds;
while (s > -1)
{
if (GameManager.restartWarningActive == true)
if (timerTextField != null)
timerTextField.text = s.ToString();
yield return new WaitForSeconds(countdownInterval);
s -= countdownInterval;
}
if (s == -1)
{
if (GameManager.restartWarningActive == true)
RestartGame();
}
}
void StopTimer()
{
Debug.Log("Restart Cancelled");
StopCoroutine(counter);
Destroy(timerDialogBoxInstance);
}
void RestartGame()
{
SceneManager.LoadScene(startingScene.name);
}
}
I think I know where your error is. When you create an instance of the countdownTimer. You have to store a reference to it in order to get the underlying CountdownTimer class.
Try doing this, in your GameManager Class
private GameObject countDownTimerInstance;
Awake()
countDownTimerInstance = Instantiate(countdownTimer);
and in the Start() do,
countdownInstance = countdownTimerInstance.GetComponent<CountdownTimer>();
I think the problem was you were directly accessing the prefab's getComponent() instead of the instantiated gameObject's CountdownTimer!.

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