I have been following this great tutorial:
https://www.youtube.com/watch?v=uxrKE2VKvmc
and at some point it does this for each target, it creates a gameObject ?
If you look at the code here:
private void SetupTargets(List<TrackableBehaviour> allTargets)
{
Debug.Log("Listing all Targets names:");
foreach (TrackableBehaviour target in allTargets)
{
Debug.Log("Target's name:" + target.TrackableName);
target.gameObject.transform.parent = transform;
target.gameObject.name = target.TrackableName;
target.gameObject.AddComponent<PlaneManager>();
Debug.Log(target.TrackableName + " created!");
}
}
why this line of code ?
target.gameObject.transform.parent = transform;
If I comment it out it still works fine..
The full class code is below:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Vuforia;
using System.Linq;
public class TargetManager : MonoBehaviour
{
public String mStartingMarkerDatabaseName = "";
private List<TrackableBehaviour> mAllTargets = new List<TrackableBehaviour>();
private void Awake()
{
VuforiaARController.Instance.RegisterVuforiaStartedCallback(onVuforiaStarted);
}
private void onDestroy()
{
VuforiaARController.Instance.UnregisterVuforiaStartedCallback(onVuforiaStarted);
}
private void onVuforiaStarted()
{
LoadDatabase(mStartingMarkerDatabaseName);
mAllTargets = GetTargets();
SetupTargets(mAllTargets);
}
private void LoadDatabase(string name)
{
ObjectTracker objectTracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
objectTracker.Stop();
if (DataSet.Exists(name))
{
DataSet dataSet = objectTracker.CreateDataSet();
dataSet.Load(name);
objectTracker.ActivateDataSet(dataSet);
}
objectTracker.Start();
}
private List<TrackableBehaviour> GetTargets()
{
List<TrackableBehaviour> allTrackables = new List<TrackableBehaviour>();
allTrackables = TrackerManager.Instance.GetStateManager().GetTrackableBehaviours().ToList();
return allTrackables;
}
private void SetupTargets(List<TrackableBehaviour> allTargets)
{
Debug.Log("Listing all Targets names:");
foreach (TrackableBehaviour target in allTargets)
{
Debug.Log("Target's name:" + target.TrackableName);
target.gameObject.transform.parent = transform;
target.gameObject.name = target.TrackableName;
target.gameObject.AddComponent<PlaneManager>();
Debug.Log(target.TrackableName + " created!");
}
}
}
target.gameObject.transform.parent = transform;
That code means that the target gameObject will be a child of whatever gameObject the TargetManager script is attached to.
As derHugo pointed out in the comments, it's redundant and can just be written as
target.transform.parent = transform;
Related
Hello? I'm studying the MIRROR Network Now.
enter image description here
However, I have a problem about getting other player's value. This image explain what I want to do.
enter image description here
I create 3 projects. One is server(local host) and other is Client A , the other is Client B.
Firstly, I wrote code like this :
public class PlayerManager : NetworkBehaviour
{
[SyncVar(hook = nameof(onValueChanged))]
int value = 0;
private void Update()
{
if(isServer && Input.GetKeyDown("x"))
{
Message();
}
}
public override void OnStartServer()
{
Debug.Log("Here is Game Room Scene, Player add Successfully");
}
[Command]
private void Hola()
{
value++;
Debug.Log("Received Hola from the client!");
Debug.Log("Server Value : " + value);
ReplyHola();
}
[TargetRpc]
private void ReplyHola()
{
Debug.Log("Received Hola from Client!");
}
[ClientRpc]
private void Message()
{
Debug.Log("Ping...");
}
[ClientRpc]
private void UpdateValue(int value)
{
this.value = value;
}
private void onValueChanged(int oldValue, int newValue)
{
Debug.Log("New Value Detective :");
Debug.Log("Old Value : " + oldValue);
Debug.Log("New Value : " + newValue);
Debug.Log("Sum Value : " + PlayerStat.Value);
}
}
3 Projects have all same code. I referenced code from this video(https://www.youtube.com/watch?v=8tKFF0RP9Jw).
And, I wrote code about sum client A and B's code like this:
private void SumDatas()
{
foreach(var playerObj in FindObjectsOfType(typeof(GameObject)) as GameObject[])
{
if(gameObject.name == "Player(Clone)")
{
PlayerStat.Value += GameObject.Find("Player(Clone)").transform.GetComponent<PlayerManager>().GetValue();
}
}
}
PlayerStat is a static class and Code is like this:
public static class PlayerStat
{
public static int Value { get; set; }
}
Is there anybody help me?
I solved this problem. I will not delete this question for other people who will have same problem with me.
I add this code at my server project, Client A and B project:
[SyncVar(hook = nameof(onValueChanged))]
int value = 0;
int myValue = 0;
private void Update()
{
myValue = PlayerStat.Value;
}
I really need help, when I put Invoke in C#, I have this error:
The local function 'RestartGame' is declared but never used Assembly-CSharp
I really don't know why it is happening, but here is the code:
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
bool gameHasEnded = false;
public float restartDelay = 2f;
public void EndGame()
{
if (gameHasEnded == false)
{
gameHasEnded = true;
Debug.Log("GAME OVER");
Invoke("RestartGame", restartDelay);
}
void RestartGame ()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
}
unity manual: For better performance and maintability, use Coroutines instead.
https://docs.unity3d.com/ScriptReference/MonoBehaviour.Invoke.html
Try someting like this:
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
bool gameHasEnded = false;
public float restartDelay = 2f;
private IEnumerator coroutine;
public void EndGame()
{
if (gameHasEnded == false)
{
gameHasEnded = true;
Debug.Log("GAME OVER");
coroutine = RestartDelayed(restartDelay);
StartCoroutine(coroutine);
}
void RestartGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
IEnumerator RestartDelayed(float delay)
{
yield return new WaitForSeconds(delay);
RestartGame();
}
}
}
https://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html
I upvoted flyingchris answer but just to explain your error message, I'm assuming its a yellow warning message, is that you are never calling the method RestartGame() directly anywhere in your code, you are invoking it however. Invoking is typically used for UnityEvents and coroutines are typically used for delaying a method.
I figured out how to create an asset bundle containing an animation clip, and then loading that animation clip in another project and then overriding existing animation clip with the new one via a script. Basically the goal is to allow users to edit animations.
Everything now thankfully works, but for some reason there is a slowdown. I am not sure what is causing the slowdown when everything is being loaded in start frame:
Here is my code:
protected Animator animator;
protected AnimatorOverrideController animatorOverrideController;
protected AnimationClipOverrides clipOverrides;
void Start()
{
animator = GetComponent<Animator>();
animatorOverrideController = new AnimatorOverrideController(animator.runtimeAnimatorController);
animator.runtimeAnimatorController = animatorOverrideController;
clipOverrides = new AnimationClipOverrides(animatorOverrideController.overridesCount);
animatorOverrideController.GetOverrides(clipOverrides);
LoadAnimation();
}
public void LoadAnimation()
{
StartCoroutine(LoadAnimClip());
}
IEnumerator LoadAnimClip(string )
{
var FilePath = Application.streamingAssetsPath + "/Characters/Sonic/Animations/stand";
var req = AssetBundle.LoadFromFileAsync(FilePath);
yield return req;
AssetBundle animationAsset = req.assetBundle;
AnimationClip animation = animationAsset.LoadAsset<AnimationClip>("Stand") as AnimationClip;
clipOverrides["Idle"] = animation;
animatorOverrideController.ApplyOverrides(clipOverrides);
}
If you are wondering what is animationclipoverrides, here is the class:
public class AnimationClipOverrides : List<KeyValuePair<AnimationClip, AnimationClip>
{
public AnimationClipOverrides(int capacity) : base(capacity) { }
public AnimationClip this[string name]
{
get { return this.Find(x => x.Key.name.Equals(name)).Value; }
set
{
int index = this.FindIndex(x => x.Key.name.Equals(name));
if (index != -1)
this[index] = new KeyValuePair<AnimationClip, AnimationClip>(this[index].Key, value);
}
}
}
I have recently been creating a game with tutorials. Unfortunately, they didn't cover a save score feature. Thanks to another user, I was able to figure out that I needed to use playerprefs. I watched tutorials online, but none of them were helpful. If you can, please help me!
Gold Per Sec Script:
using UnityEngine;
using System.Collections;
public class GoldPerSec : MonoBehaviour {
public UnityEngine.UI.Text gpsDisplay;
public Click click;
public ItemManager[] items;
void Start () {
StartCoroutine(AutoTick ());
}
void Update () {
gpsDisplay.text = GetGoldPerSec() + " Money Per Sec";
}
public float GetGoldPerSec() {
float tick = 0;
foreach (ItemManager item in items) {
tick += item.count * item.tickValue;
}
return tick;
}
public void AutoGoldPerSec() {
click.gold += GetGoldPerSec() / 10;
}
IEnumerator AutoTick() {
while (true) {
AutoGoldPerSec();
yield return new WaitForSeconds(0.10f);
}
}
}
Gold Per Click script:
using UnityEngine;
using System.Collections;
public class Click : MonoBehaviour {
public UnityEngine.UI.Text gpc;
public UnityEngine.UI.Text goldDisplay;
public float gold = 0.00f;
public int goldperclick = 1;
void Update () {
goldDisplay.text = "" + gold.ToString("F0");
gpc.text = "Money Per Click: " + goldperclick;
}
public void Clicked(){
gold += goldperclick;
}
}
My idea was for the game to save when the game is quit, and load as soon as you load the game back up. I am a complete beginner, if anyone can tell me how to do this, please tell me! Thanks! :D
You can use unity's existing functions to achieve this.
For saving data use unity's OnApplicationQuit function like this
void OnApplicationQuit() {
PlayerPrefs.SetFloat("key", value);
}
And for Restoring the values use unity's Awake function like this
void Awake(){
value = PlayerPrefs.GetFloat("key");
}
Please note that PlayerPrefs is an easy way to save data but also an very unsafe way. The player can easily manipulate his "goldValue" since it's just stored as an integer in some file on his device. PlayerPrefs should usually just be used for values the player can changed any way within in game, like volume setting etc.
EXAMPLE CODE
void Save()
{
string filename = "/filename.dat";
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(Application.persistentDataPath+filename);
bf.Serialize(file, goldValue); //Use can easily use e.g. a List if you want to store more date
file.Close();
}
bool Load()
{
string filename = "/filename.dat";
if (File.Exists(Application.persistentDataPath + filename))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + filename, FileMode.Open);
goldValue=(int) bf.Deserialize(file);
file.Close();
return true;
}
return false;
}
Add the following code to Click class:
void Awake()
{
LoadData();
}
void OnApplicationQuit()
{
SaveData();
}
void SaveData()
{
PlayerPrefs.SetFloat("gold",gold);
}
void LoadData()
{
gold = PlayerPrefs.GetFloat("gold",0f);
}
I have an Inventory system working and when I picked up an item it would go into it but I'm not sure what I changed because the item won't be picked up anymore. I'm trying to everything I can but now the only time I can add an item to my inventory is through the start function where it was initialized.
Here is the code attached to the player
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class BasePlayer : MonoBehaviour {
private List<BaseStat> _playerStats = new List<BaseStat> ();
private List<BaseItem> _playerInventory = new List<BaseItem>();
void Start () {
BaseItem _item = new BaseItem ();
BaseItem _weapon = new BaseItem ();
_weapon.ItemType = BaseItem.ItemTypes.WEAPON;
BaseItem _potion = new BaseItem();
_potion.WeaponType = BaseItem.WeaponTypes.BOW;
_potion.ItemType = BaseItem.ItemTypes.POTION;
_playerInventory.Add (_item);
_playerInventory.Add (_weapon);
_playerInventory.Add (_potion);
}
public List<BaseItem> ReturnPlayerInventory() {
return _playerInventory;
}
}
Here is the code attached to the item
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Avalon : MonoBehaviour {
private List<BaseItem> playerInventory = new List<BaseItem>();
public GameObject Sword;
void Start () {
BasePlayer basePlayerScript = GameObject.FindGameObjectWithTag ("Player").GetComponent<BasePlayer> ();
playerInventory = basePlayerScript.ReturnPlayerInventory ();
}
void OnTriggerEnter2D(Collider2D col) {
if (col.CompareTag ("Player")) {
GreatSwordAvalon ();
Destroy (Sword.gameObject);
}
}
public void GreatSwordAvalon() {
BaseItem _avalon = new BaseItem ();
_avalon.ItemName = "GreatSword of Avalon";
_avalon.ItemDescription = "Strongest sword in the game";
_avalon.ItemType = BaseItem.ItemTypes.WEAPON;
_avalon.ItemValue = 999999;
_avalon.ItemStats.Add (new BaseStrength ());
_avalon.WeaponType = BaseItem.WeaponTypes.SWORD;
playerInventory.Add (_avalon);
}
}
Any help is greatly appreciated
I ended up solving the problem myself. In my Inventory Window script I have a function called AddItemsFromInventory that checks everything in the player inventory and adds it into the Inventory window.
The problem was that I had the call to the function in the start instead of the update so it constantly checks instead of just in the beginning.