Assignment in Unity script - c#

I want to develop an experimental program in unity. In the program, I use scripts to create a series of objects and assign values to them. I use Tobii's SDK to develop an eye movement experimental program. In order to get the line of sight feedback of these objects (actually a ray collision detection principle), I created a script and added this script for each object. But when I run, I find that only the last of the series of objects I create will give correct feedback, and the other objects will not give feedback。
My feedback script is as follow:
void Update () {
if (_gazeAwareComponent.HasGazeFocus) {
img.color = _outColor;
newText = textName.text;
MainInteraction.isEnter = true;
} else {
img.color = initinalColor;
newText = null;
MainInteraction.isEnter = false;
}
}
I use a static variable to control the state of feedback.
And in my main script, my fuction is:
void createTargetAndText (int number) {
int[] a = GetRandomSequence(10, currentTrailTime);
for (int i = 0; i < number; i++) {
GameObject image = new GameObject();
image.transform.localScale = Vector3.one;
image.name = a[i].ToString();
image.AddComponent<Image>();
image.AddComponent<SphereCollider>();
image.GetComponent<SphereCollider>().radius = targetSize / 2;
image.AddComponent<Feedback>();
image.GetComponent<Image>().sprite = sourceImage;
image.transform.SetParent(currentGameObject.transform.GetChild(3).transform);
image.layer = LayerMask.NameToLayer("UI");
GameObject textGame = new GameObject();
textGame.name = a[i].ToString();
textGame.AddComponent<Text>();
textGame.GetComponent<Text>().font = textFont;
textGame.GetComponent<Text>().text = textGame.name;
textGame.GetComponent<Text>().fontSize = 48;
textGame.GetComponent<Text>().alignment = TextAnchor.MiddleCenter;
textGame.GetComponent<Text>().color = Color.black;
textGame.transform.SetParent(image.transform);
textGame.layer = LayerMask.NameToLayer("UI");
}
}
The only problem is MainInteration.isEnter doesn't work, when I try to change the color to debug, it works.
if (_gazeAwareComponent.HasGazeFocus) {
img.color = _outColor;
newText = textName.text;
MainInteraction.isEnter = true;
if (this.name == "2") {
MainInteraction.isEnter = true;
img.color = Color.cyan;
}
}
I guess the problem may come from:
the static variables in Unity.
Can someone help me answer it? Thank you

Related

How to create and run animation at runtime?

I'm making a game currently and want to create and run an animation at runtime.
This is what I got so far:
void Start()
{
Sprite[] sprites = upgrades.GetComponent<uprgades>().sprites;
AnimationClip animClip = new AnimationClip();
animClip.frameRate = 60;
EditorCurveBinding spriteBinding = new EditorCurveBinding();
spriteBinding.type = typeof(SpriteRenderer);
spriteBinding.path = "";
spriteBinding.propertyName = "m_Sprite";
ObjectReferenceKeyframe[] spriteKeyFrames = new ObjectReferenceKeyframe[sprites.Length];
for(int j = 0; j < (sprites.Length); j++)
{
spriteKeyFrames[j] = new ObjectReferenceKeyframe();
spriteKeyFrames[j].time = j;
spriteKeyFrames[j].value = sprites[j];
}
AnimationUtility.SetObjectReferenceCurve(animClip, spriteBinding, spriteKeyFrames);
AnimationClipSettings animClipSett = new AnimationClipSettings();
animClipSett.loopTime = true;
animClip.legacy = true; //added
AnimationUtility.SetAnimationClipSettings(animClip, animClipSett);
I don't understand everything completely cause I found this in the internet. But now I need to start the animation. So I did this:
Animation anim = someGameObject.GetComponent<Animation>();
anim.clip = animClip;
anim.Play();
}
But this doesnt work. I think it has something to do that I don't have any Animator / or Controller but I don't know if I have to add them how and where I should do this
Where are you running the animation? Is it in the update function?

Why my camera block between two position using lerp?

im trying to make a script that allow my camera moving into 4 differents position ( front back left right ) using keyArrows and lerp.
the first movement works good, but when i hit another KeyArrow my camera move a little bit and get stucks between the first position and the end position.
There is the code :
void Update()
{
if (Input.GetKey(KeyCode.UpArrow)){
Uparr = true;
}
if (Input.GetKey(KeyCode.DownArrow)){
DownAarr= true;
}
if (Input.GetKey(KeyCode.RightArrow)){
Rightarr = true;
}
if (Input.GetKey(KeyCode.LeftArrow)){
Leftarr = true;
}
//boolean
if(Uparr){
cam.transform.LookAt(target);
cam.transform.position = Vector3.Lerp(StartPos.position,endPosition1.position,lerpSpeed*Time.deltaTime);
if (cam.transform.position == endPosition1.position){
Uparr = false;
}
}
if(DownAarr){
cam.transform.LookAt(target);
cam.transform.position = Vector3.Lerp(StartPos.position,endPosition2.position,lerpSpeed*Time.deltaTime);
if (cam.transform.position == endPosition2.position){
DownAarr = false;
}
}
if(Rightarr){
cam.transform.LookAt(target);
cam.transform.position = Vector3.Lerp(StartPos.position,endPosition3.position,lerpSpeed*Time.deltaTime);
if (cam.transform.position == endPosition3.position){
Rightarr = false;
}
}
if (Leftarr){
cam.transform.LookAt(target);
cam.transform.position = Vector3.Lerp(StartPos.position,endPosition4.position,lerpSpeed*Time.deltaTime);
if (cam.transform.position == endPosition4.position){
Leftarr = false;
}
}
do you know what it can be the problem ?
You need to set the other direction variables to false when setting the new direction. Multiple views are active at once, and thus, they are fighting.
if (Input.GetKey(KeyCode.UpArrow)){
Leftarr = false;
Downarr = false;
Rightarr = false;
Uparr = true;
}
It may be easier to store one variable for direction but to each their own.

How can I return from a method also List of transforms or gameobjects without making instances fro new gameobjects?

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine.SceneManagement;
public static class TransformSaver
{
[System.Serializable]
public class TransformInfo
{
public string sceneName;
public string name;
public Transform parent;
public Vector3 pos;
public Quaternion rot;
public Vector3 scale;
}
//Save Transform
public static void SaveTransform(Transform[] tranformToSave)
{
TransformInfo[] trnfrm = new TransformInfo[tranformToSave.Length];
for (int i = 0; i < trnfrm.Length; i++)
{
trnfrm[i] = new TransformInfo();
trnfrm[i].sceneName = tranformToSave[i].gameObject.scene.name;
trnfrm[i].name = tranformToSave[i].name;
trnfrm[i].parent = tranformToSave[i].parent;
trnfrm[i].pos = tranformToSave[i].localPosition;
trnfrm[i].rot = tranformToSave[i].localRotation;
trnfrm[i].scale = tranformToSave[i].localScale;
}
string jsonTransform = JsonHelper.ToJson(trnfrm, true);
File.WriteAllText(#"d:\json\json.txt", jsonTransform);
}
//Load Transform
public static Transform[] LoadTransform()
{
string jsonTransform = File.ReadAllText(#"d:\json\json.txt");
if (jsonTransform == null)
{
return null;
}
TransformInfo[] savedTransforms = JsonHelper.FromJson<TransformInfo>(jsonTransform);
GameObject[] gameObjects = new GameObject[savedTransforms.Length];
Transform[] loadedTransforms = new Transform[savedTransforms.Length];
for (int i = 0; i < gameObjects.Length; i++)
{
SceneManager.SetActiveScene(SceneManager.GetSceneByName(savedTransforms[i].sceneName));
gameObjects[i] = new GameObject();
loadedTransforms[i] = gameObjects[i].transform;
loadedTransforms[i].name = savedTransforms[i].name;
loadedTransforms[i].parent = savedTransforms[i].parent;
loadedTransforms[i].localPosition = savedTransforms[i].pos;
loadedTransforms[i].localRotation = savedTransforms[i].rot;
loadedTransforms[i].localScale = savedTransforms[i].scale;
}
return loadedTransforms;
}
}
The problem is that the method LoadTransform will return array of Transforms but also will create new GameObjects in the Editor in the Hierarchy.
What I want to do is to add something like a boolean flag or maybe other way so I can select if toe return the array of transforms with or without creating new gameobjects so I tried something like that:
//Load Transform
public static Transform[] LoadTransform(bool returnInfo)
{
string jsonTransform = File.ReadAllText(#"d:\json\json.txt");
if (jsonTransform == null)
{
return null;
}
TransformInfo[] savedTransforms = JsonHelper.FromJson<TransformInfo>(jsonTransform);
GameObject[] gameObjects = new GameObject[savedTransforms.Length];
Transform[] loadedTransforms = new Transform[savedTransforms.Length];
for (int i = 0; i < gameObjects.Length; i++)
{
SceneManager.SetActiveScene(SceneManager.GetSceneByName(savedTransforms[i].sceneName));
if (returnInfo == true)
{
gameObjects[i] = new GameObject();
loadedTransforms[i] = gameObjects[i].transform;
}
loadedTransforms[i].name = savedTransforms[i].name;
loadedTransforms[i].parent = savedTransforms[i].parent;
loadedTransforms[i].localPosition = savedTransforms[i].pos;
loadedTransforms[i].localRotation = savedTransforms[i].rot;
loadedTransforms[i].localScale = savedTransforms[i].scale;
}
return loadedTransforms;
}
I added a bool flag returnInfo but now loadedTransforms is null.
But the main goal is to decide if to return array of transforms with or without making instances for new gameobjects.
The problem is when I'm using Editorwindow type script and inside OnGUI to save and load the objects:
List<GameObject> selections = Selection.objects.OfType<GameObject>().ToList();
if (selections.Count > 0)
{
GUI.enabled = true;
}
else
{
GUI.enabled = false;
}
if (GUILayout.Button("Save selected objects data"))
{
if (selections.Count > 0)
{
tempTransformSelection = selections;
for (var i = selections.Count - 1; i >= 0; --i)
{
var selected = selections[i];
transformSelection.Add(selected.transform);
}
TransformSaver.SaveTransform(transformSelection.ToArray());
transformSelection = new List<Transform>();
}
}
var file = #"d:\json\json.txt";
FileInfo fi = new FileInfo(file);
// By default asume you don't want to show the button
// it will than only be enabled if the later conditions match
bool showButton = false;
// you can check this already here not in the loop
// if no file -> nothing to do
if (!File.Exists(#"d:\json\json.txt") || fi.Length <= 0) return;
// This is only reached if the file exists and is not empty
// check for null transforms
for (int i = 0; i < tempTransformSelection.Count(); i++)
{
// if not null do nothing
if (tempTransformSelection[i] != null)
continue;
// otherwise enable the button and leave the loop
showButton = true;
break;
}
// if not true then button won't be shown
if (showButton == true)
{
GUI.enabled = true;
}
else
{
GUI.enabled = false;
}
if (GUILayout.Button("Instantiate back deleted selected bojects"))
{
TransformSaver.LoadTransform(true);
showButton = false;
}
}
private void OnInspectorUpdate()
{
Repaint();
}
The main goal is to select objects in the hierachy in the editor. Then to click on "Save selected objects data" to save the selected object to a json file.
Then I want to make that only if one of the saved objects to the file is null in the hierarchy fro example if I deleted one or more of the objects in the saved file ! only then enable true the button "Instantiate back deleted selected bojects"
And then when clicking on the button "Instantiate back deleted selected bojects" set the button back to enabled false !
But the important thing is to check for null against the saved list of objects in the json file ! But once again I'm stuck with the tempTransformSelection and with how to enable false/true the button.

Unity3d : Creating GUIText On Runtime

I am trying to create a Text that describes an object on Runtime, the GUIText object is created but it is not visible. any ideas ?
here is my code :
void enemydescriptionInit( GameObject text, string desc){
text.transform.parent = enemyCar1.car.transform;
enemyCar1.car.transform.position = enemyCar1.startPosiotion;
text.gameObject.GetComponent<GUIText> ().font = new Font ("Arial");
text.gameObject.GetComponent<GUIText>().text = desc;
text.gameObject.GetComponent<GUIText>().fontSize = 40;
text.gameObject.GetComponent<GUIText>().fontStyle = FontStyle.BoldAndItalic;
text.gameObject.GetComponent<GUIText>().color = Color.blue;
text.gameObject.name = "Desc";
}
void Start () {
player = GameObject.Find ("Player");
text = new GameObject();
text.AddComponent<GUIText>();
}
void Update(){
enemydescriptionInit (text, "HELLO");
}
If you're using Unity 5 try using UnityEngine.UI
And instead of GUITextjust use Text
Hope it helps
Try on OnGUI() method
this example code
void OnGUI(){
GUIStyle style = new GUIStyle();
style.fontSize = 30;
style.alignment = TextAnchor.UpperRight;
GUI.Label (new Rect(Screen.width/2 , 10 , 100 ,40) , "Time left " + secondsLeft.ToString() , style);
}

Can´t check if array values are true from another class in main class

I am programming a basic writing game in C#. The game will randomly show picture in a picturebox. The pictures is stored in an array in a different class than the main class.
The code to the class looks like this :
public class bildelisteDyr
{
public static Bitmap bildeListe (int index)
{
Bitmap[] bildeListe = new Bitmap[21];
bildeListe[0] = Properties.Resources.ål;
bildeListe[1] = Properties.Resources.ant;
bildeListe[2] = Properties.Resources.bird;
bildeListe[3] = Properties.Resources.bear;
bildeListe[4] = Properties.Resources.butterfly;
bildeListe[5] = Properties.Resources.cat;
bildeListe[6] = Properties.Resources.chicken;
bildeListe[7] = Properties.Resources.dog;
bildeListe[8] = Properties.Resources.elephant;
bildeListe[9] = Properties.Resources.fish;
bildeListe[10] = Properties.Resources.goat;
bildeListe[11] = Properties.Resources.horse;
bildeListe[12] = Properties.Resources.ladybug;
bildeListe[13] = Properties.Resources.lion;
bildeListe[14] = Properties.Resources.moose;
bildeListe[15] = Properties.Resources.polarbear;
bildeListe[16] = Properties.Resources.reke;
bildeListe[17] = Properties.Resources.sheep;
bildeListe[18] = Properties.Resources.snake;
bildeListe[19] = Properties.Resources.spider;
bildeListe[20] = Properties.Resources.turtle;
return bildeListe[index];
}
}
When calling on the values in the array to show picture randomly in the picturebox it all works well. This is done like this :
pictureBox1.Image = bildelisteDyr.bildeListe(r.Next(0, 20));
But I have three times where I need the code to check the value of the picturebox to do a something. I have one play sound button, one button that give a label a text and one button to check given answer from a textbox. None of them seems to work. Here are some code :
Give text to label :
if (pictureBox1.Image == bildelisteDyr.bildeListe(0))
{
svarPåOppgave.Text = "ÅL";
}
else if (pictureBox1.Image == bildelisteDyr.bildeListe(1))
{
svarPåOppgave.Text = "MAUR";
}
// etc.
Play sound button :
if (pictureBox1.Image == bildelisteDyr.bildeListe(0))
{
SoundPlayer player = new SoundPlayer();
player = new SoundPlayer("lyd/dyr/ål.wav");
player.PlaySync();
}
else if (pictureBox1.Image == bildelisteDyr.bildeListe(1))
{
SoundPlayer player = new SoundPlayer();
player = new SoundPlayer("lyd/dyr/enmaur.wav");
player.PlaySync();
}
// etc.
Checking if correct answer is given :
if (pictureBox1.Image == bildelisteDyr.bildeListe(0))
{
if (textBox1.Text.Trim().ToLower() == "ål")
{
riktigLyd.Play();
poengInt += 1;
textBox1.Text = "";
pictureBox1.Image = bildelisteDyr.bildeListe(tilfeldigBildet);
tekstTilLabel();
svarPåOppgave.Visible = false;
}
else
{
feilLyd.Play();
poengInt -= 1;
textBox1.Text = "";
}
String poengString = poengInt.ToString();
label1.Text = poengString;
textBox1.Select();
}
else if (pictureBox1.Image == bildelisteDyr.bildeListe(1))
{
if (textBox1.Text.Trim().ToLower() == "maur")
{
riktigLyd.Play();
poengInt += 1;
textBox1.Text = "";
pictureBox1.Image = bildelisteDyr.bildeListe(tilfeldigBildet);
tekstTilLabel();
svarPåOppgave.Visible = false;
}
else
{
feilLyd.Play();
poengInt -= 1;
textBox1.Text = "";
}
String poengString = poengInt.ToString();
label1.Text = poengString;
} // etc.
I would guess there was something wrong with the if statements like
if (textBox1.Text.Trim().ToLower() == "ål")
But I can´t seem to understand what?
To sum it up, when I debug the program I get the random picture from the other class. But when I press the buttons on the program nothing happens. No sound, no text to label and no checking of answer.
There's some unusual architectural choices here, but the specific problem you're facing is that you're re-creating the Bitmaps every time, and comparisons are performed by reference, not by value.
Change your bildelisteDyr class as follows:
public class bildelisteDyr
{
static Bitmap[] bildeListeInternal;
static bildelisteDyr() {
bildeListeInternal = new Bitmap[21];
bildeListeInternal[0] = Properties.Resources.ål;
//...
bildeListeInternal[20] = Properties.Resources.turtle;
}
public static Bitmap bildeListe (int index) {
return bildeListeInternal[index];
}
}
Some more resources on the conceptual problem:
== Operator
Value vs Reference Types

Categories