In the first script:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LightsEffects : MonoBehaviour
{
public enum Directions
{
Forward, Backward
};
private Renderer[] renderers;
private float lastChangeTime;
private int greenIndex = 0;
public void LightsEffect(List<GameObject> objects, Color instantiateColor, Color colorEffect)
{
renderers = new Renderer[objects.Count];
for (int i = 0; i < renderers.Length; i++)
{
renderers[i] = objects[i].GetComponent<Renderer>();
renderers[i].material.color = Color.red;
}
// Set green color to the first one
greenIndex = 0;
renderers[greenIndex].material.color = Color.green;
}
public void LightsEffectCore(float delay, bool changeDirection)
{
// Change color each `delay` seconds
if (Time.time > lastChangeTime + delay)
{
lastChangeTime = Time.time;
// Set color of the last renderer to red
// and the color of the current one to green
renderers[greenIndex].material.color = Color.red;
if (changeDirection == true)
{
Array.Reverse(renderers);
changeDirection = false;
}
greenIndex = (greenIndex + 1) % renderers.Length;
renderers[greenIndex].material.color = Color.green;
}
}
}
In this script i want to use the enum Directions instead the bool in the core method:
public void LightsEffectCore(float delay, bool changeDirection)
Instead bool changeDirection to use the enum to decide what direction Forward or Backward.
And then to use this script in another one for example in another script i did:
public LightsEffects lightseffect;
Then in Start:
void Start()
{
lightseffect.LightsEffect(objects, Color.red, Color.green);
}
Then in Update i want to decide the direction:
void Update()
{
lightseffect.LightsEffectCore(0.1f, false);
}
But instead false/true i want to use also here Forward/Backward
Maybe something like:
lightseffect.LightsEffectCore(0.1f, lightseffect.Forward);
Since false/true not really have a meaning of what it's doing.
Another option is to leave it with false/true but to add a description to the method when the user typing: lightseffect.LightsEffectCore(
When he type ( he will see a description of what the method do and when he will type ,
It will tell him what the false/true will do. But i'm not sure how to make a description for that.
Directions is the name of the enum you're interested in. It's also contained within the LightsEffects class.
Thus the way to reference it somewhere else would be LightsEffects.Directions and then another dot and then the value (Forward,etc). This is similar to a Fully Qualified Name, but with part of that scope already declared (whatever import/using that gets you LightsEffects).
So your line:
lightseffect.LightsEffectCore(0.1f, lightseffect.Forward);
Becomes:
lightseffect.LightsEffectCore(0.1f, LightsEffects.Directions.Forward);
Depending on your IDE, it should even be able to resolve this for you if you had used Directions.Forward: your IDE would have noticed the error (unknown reference Directions) and suggested a fix (change to LightsEffects.Directions), I know that Visual Studio does this, as I have a similar case in a project I'm working on now.
Related
so i'm trying to do a little game on unity . And i did a script , when you press left click on an object , it open a canvas and another one and then it add +1 to i , like that when i found every object . (so when i=3) it shows the end screen. But when i go in game mode , when i press left click it doesnt add the number , like every object have his same i , but i dont understand they have the same function no ?
And sometimes 2 of 3 works, i dont know if thats clear to understand.
using UnityEngine;
using UnityEngine.UI;
public class ActionObjet : MonoBehaviour
{
public Image image1;
public Image image2;
public Image image3;
public int i = 0;
void Start()
{
image1.enabled = false;
image2.enabled = false;
image3.enabled = false;
}
void Update()
{
if (Input.GetKeyDown("space"))
{
if (image1.enabled == true)
{
i = i + 1;
print(i);
image2.enabled = !image2.enabled;
image1.enabled = !image1.enabled;
FindObjectOfType<AudioManager>().Play("bruit_recuperer_objet");
}
}
}
void OnMouseDown()
{
if (image1.enabled == false)
{
image1.enabled = !image1.enabled;
}
}
}
https://i.stack.imgur.com/sOSJH.png
So I found the solution , I'm a bit sad that I wasted 5 hours just for that but yea..
I just changed the
public int i=0
into
static int i=0;
This is because each gameObject with this script has its own instance of all the variables. A static variable's value is universal to all instances of the same class so any one of them can update it for all of them when marked static.
The answer to the boolean issue provided by #Mario below solved the main issue as well
The code in the original post (below the line) had an unrelated problem ('==' instead of '=') but in fixing that I've realized that I am having an issue with the string name of 'cubeRend.material' which includes the additive Instance after it and therefore doesn't seem to be counted as logically equal to the string name of 'material[0].'
I don't THINK that is the issue behind the resetting problem however, because I did find a question about a similar resetting problem on the Unity answer forum here: https://answers.unity.com/questions/1303925/ui-buttons-images-resets-after-scene-reloads-scrip.html
Unfortunately no one provided any responses to that question which I could try to apply in this case. I will try to sort out my equivalency problem and then update with the improved code
I'm trying to make a UI button change the colors on a cube on every click. The materials are in an array. In the start function, I set the initial condition of the cube's renderer to material[0]. In the ChangeCubeColor function (which is referred to on the UI button's inspector), I use a simple if/else statement to check which material is currently assigned to the cube. On clicking the button, Unity seems to reset the material back to the original condition and then invisible to the eye follow the if/else instructions to set the color to the 2nd color in the array. The affect is that on the first time you play, the button will change the color, but every time after that, the color is stuck on the second color.
Here is my code. I apologize for all of the debug statements. I was trying to figure out when the state was or was not changing. I've also included a screenshot of my console upon first play and the first 3 clicks of the button. Lastly, the code with the debug statements removed for clarity.
Thanks in advance for any ideas.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeCubeColor : MonoBehaviour
{
public Material[] material;
Renderer cubeRend;
void Start()
{
cubeRend = GetComponent<Renderer>();
cubeRend.material = material[0];
Debug.Log(cubeRend.material);
}
public void CubeColorChange()
{
if(cubeRend.material = material[0])
{
Debug.Log("cubeRend.material = material[0]");
cubeRend.material = material[1];
Debug.Log("Make 1: "+cubeRend.material);
Debug.Log("cubeRend.material = material[1]");
}
else if (cubeRend.material = material[1])
{
Debug.Log("cubeRend.material = material[1]");
cubeRend.material = material[0];
Debug.Log("Make 0: " + cubeRend.material);
Debug.Log("cubeRend.material = material[0]");
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeCubeColor : MonoBehaviour
{
public Material[] material;
Renderer cubeRend;
void Start()
{
cubeRend = GetComponent<Renderer>();
cubeRend.material = material[0];
}
public void CubeColorChange()
{
if(cubeRend.material = material[0])
{
cubeRend.material = material[1];
}
else if (cubeRend.material = material[1])
{
cubeRend.material = material[0];
}
}
}
Try this way. This work for 2 materials if you want more you can use an int index and update the index without use if for each material
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeCubeColor : MonoBehaviour
{
public Material[] material;
public bool state;
Renderer cubeRend;
void Start()
{
cubeRend = GetComponent<Renderer>();
cubeRend.material = material[0];
//state = false is material 0 //state = true is material 1
state = false;
}
public void CubeColorChange()
{
//Change the state to the other state
state = !state;
cubeRend.material = (state) ? material[1] : material[0];
}
}
EDIT 1:
Here is the variation with index for more materials
using UnityEngine;
public class ChangeCubeColor : MonoBehaviour
{
public Material[] material;
public int index;
Renderer cubeRend;
void Start()
{
cubeRend = GetComponent<Renderer>();
index = 0;
cubeRend.material = material[index];
}
public void CubeColorChange()
{
//Increase index
index = (material.Length - 1 > index) ? index + 1 : 0;
cubeRend.material = material[index];
}
}
I am trying to create a game in Unity 2d. I have finished most of what I want to do and have moved on to the enemies. The enemies (dragons) come in from different points of screen. To do this I have placed sprite game objects where I want the dragon to spawn. I have made all of these objects a child of another object called DragonAncores. I attached a script to DragonAncores which says this...
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DragonTracker : MonoBehaviour {
// is gold dragon in play?
public bool GoldDragonInit = false;
// curently active dragons
public int DragonCount = 0;
// defalts to 5
public int Difficulty = 5;
}
I am then attaching a script to each sprite which will eventually summon in a dragon Prefab (containing 2 colliders and an animator) biased of If statment logic derived from the other variables.
Below is the code I am using.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Dragons : MonoBehaviour {
// same as GoldDragonInit
bool GoldDragonSpawn = false;
// same number as DragonCount in DragonTrackeer
int LiveDragons;
// same as Difficulty
int DifLev;
//get cariables from other script
DragonAncors.cs.GetComponent.<DragonTracker>() GoldDragonInit = GoldDragonSpawn;
System.Random RNG= new System.Random();
void update()
{
RSpawn=RNG.Next(0,2)
DragonType=RNG.Next(0,101)
if (RSpawn = 1) ;
{
if (LiveDragons > DifLev) ;
{
if (DragonType > 99) ;
{
// summon regular dragon
}
if (DragonType = 100) ;
{
if (GoldDragonSpawn = true) ;
{
// summon gold dragon
}
}
}
}
}
}
This is throwing up this error list.
This shows my hierarchy in unity and the anchor points (the Squair crosshair looking things)
I have looked for other threads that adress this topic and they all try different methods, none work.
I am using Unity 2018.2.18f1
There are a few errors in your code here. The following is incorrect.
//get cariables from other script
DragonAncors.cs.GetComponent.<DragonTracker>() GoldDragonInit = GoldDragonSpawn;
The correct way to access this, seeing as you said DragonAncors is the parent would be:
GetComponentInParent<DragonTracker>().GoldDragonInit = GoldDragonSpawn;
This sets the GoldDragonInit Boolean to the value of GoldDragonSpawn. This has to be inside a function, as you have it outside of a function I presume you needed this set on start. Therefore I have placed it in the void Start() function. This is called at the start of the game(loaded scene).
You also do not need semi-colons ; after an if statement, however it does need to appear after every line of difinitive code. The code you have provided should instead look like this.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Dragons : MonoBehaviour {
// same as GoldDragonInit
bool GoldDragonSpawn = false;
// same number as DragonCount in DragonTrackeer
int LiveDragons;
// same as Difficulty
int DifLev;
void Start()
{
// variables from other script
GetComponentInParent<DragonTracker>().GoldDragonInit = GoldDragonSpawn;
}
System.Random RNG= new System.Random();
void update()
{
RSpawn=RNG.Next(0,2);
DragonType=RNG.Next(0,101);
if (RSpawn = 1)
{
if (LiveDragons > DifLev)
{
if (DragonType > 99)
{
// summon regular dragon
}
if (DragonType = 100)
{
if (GoldDragonSpawn = true)
{
// summon gold dragon
}
}
}
}
}
}
This works because DragonTracker is a script in the objects parent. If this was not the case then GetComponentInParent().GoldDragonInit = GoldDragonSpawn; would be replaced like so:
[SerializeField]
private GameObject DragonAncors;
void Start()
{
DragonAncors.GetComponent<DragonTracker>().GoldDragonInit = GoldDragonSpawn;
}
This is not valid c# code:
//get cariables from other script
DragonAncors.cs.GetComponent.<DragonTracker>() GoldDragonInit = GoldDragonSpawn;
Why? Because it isn't inside a method.
Also, the comment is wrong. It isn't getting a variable (typo, too), its setting a variable in another script!
The reason for the first...16 problems Visual Studio is complaining about are because of this line.
At this location you are only allowed to declare methods, fields, and properties and you're currently trying to access another class and change one of its members (something you can only do inside a method).
Additionally, you have .cs which I assume is because "DragonAnchors.cs is the file name!" which you don't need to do. I'm not sure how to go about rewriting this line (inside Start()) as I'm not sure what you're trying to actually do. That is, I don't know where an instance of DragonAnchors actually resides. You're calling GetComponent(), which is typically reserved for accessing components attached to game objects, but as you've attempted to do so on a static class reference, I'm not sure if you meant to call it on this or on something else.
This is how you can get to DragonTracker:
DragonTracker dt = GameObject.Find("DragonAncores").GetComponent<DragonTracker>()
Debug.Log(dt.DragonCount);
There are a lot of errors there and they may take some steps to go through, but first things first you should clear up the issue with the code you're trying to use being unsupported. Go into the project settings and change the compiler language version as it notes on the 5th error down. This should allow you to use the newer functionality.
Let's suppose we have two cylinders in the scenes with red and blue materials on them. Also, we have two UI images with red and blue background. Now, what should I do to make the red image only draggable onto red cylinder and the blue image only draggable onto blue cylinder.
If I drag the red image onto the blue cylinder, then an error message should appear:
same for dragging blue image on red cylinder or vice versa.
See the picture below
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class wrench : MonoBehaviour {
public bool Dragging = false;
public bool collision = false;
Vector3 position;
public List<GameObject> UIimages;
public void BeginDrag() {
position = gameObject.transform.position;
Dragging = true;
foreach (GameObject obj in UIimages) {
obj.GetComponent<BoxCollider2D> ().enabled = false;
}
}
public void Drag() {
transform.position = Input.mousePosition;
}
public void Drop() {
if (!collision) {
gameObject.transform.position = position;
}
Dragging = false;
}
}
Assuming your dropps are already detected as you say and the question is more about how to differ between the objects I would use a simple enum e.g.
public enum WhichObject
{
red,
blue
}
the advantage is that later you can very easily add more options without having to deal with layers, tags etc.
On the GameObject you drag around add a component e.g.
public class ObjectInformation
{
public WhichObject IsObject;
}
and simply select in the Inspector (or if you spawn them via script) for each of your dragged objects which value the WhichObject variable shall have.
Than on your target objects where you detect the collision also add a WhichObject variable but this time configure the value you expect to be dropped here
public WhichObject ExpectedObject;
again set it via the inspector or script.
Than simply add a check
var info = droppedObject.GetComponent<ObjectInformation>();
// Something else dropped?
if(!info) return;
// Now check if the value matches
// the one this object expects
if(info.IsObject == ExpectedObject)
{
// Correct object
Debug.Log("Yeah!");
}
else
{
// Wrong object
Debug.LogFormat("Dropped object {0} does not match the expected object {1}!", info.IsObject, ExpectedObject);
}
Later you can also simply extend it using multiple enums like e.g. colors, forms etc.
And maybe you could as well make the check the other way round and check on the dragged object, if the values match and if the don't match not even allow to be dropped on that target object (this depends of course on your implementation).
I am working on a game in UNITY. For this game so far I have 3 cubes that I wish to target. I have them set up in an array and when I hit tab the targets switch between them based on distance. This is all fine but I have run into a pickle and it is that I wish to have the cubes I target turn red for visual representation. I seen on Youtube that people used the following line of code :
selectedTarget.renderer.material.color = Color.red;
However this does not work for me. I then seen a comment saying :
The function to render was deprecated. Below should work...
selectedTarget.GetComponent<Renderer>().material.color = Color.red;
This code does not work for me either. I get no errors mind you, it runs fine but the cubes do not turn red. Has anyone any idea on whether or not I am doing this right? I will post the entire script below and the code I am on about is in selectedTarget(). Any help would be appreciated and thank you!
private void SelectTarget(){
selectedTarget.renderer.material.color = Color.red;
}
I had the very very very same problem. I had no errors. You need to be able to set the color property on the material, and only CERTAIN shaders have this color property. I had to use for example Self-Illuminated/Bumped instead of say Mobile/VertexLit. Then changing the color should be fine as you can see a Main Color property in the editor/inspector.
Also make sure your mesh has Materials. If you don't have Materials, even if it's blank or a placeholder else it won't work! I'd create a texture preferably white colored and small like 5x5. Then attach the texture to your cube. After you attach it you can color it!
I've done cool stuff in my game with Color.Lerp, it'll fade from one color to the next! This example below ping pongs from white to red when the player is hit by an enemy indicating damage!
transform.renderer.material.color = Color.Lerp(Color.white, Color.red, Mathf.PingPong(Time.time * 3 * speedLerp, 1.0));
This is working for me.
using UnityEngine;
using System.Collections;
public class Tile : MonoBehaviour {
public Vector2 gridPos = Vector2.zero;
Renderer r;
public Color colorStart = Color.red;
public Color colorEnd = Color.green;
public float duration = 1.0F;
private float lerp;
// Use this for initialization
void Start () {
r = GetComponent<Renderer>();
lerp = Mathf.PingPong(Time.time, duration) / duration;
}
// Update is called once per frame
void Update () {
}
void OnMouseEnter()
{
r.material.color = Color.Lerp(colorStart, colorEnd, lerp);
//r.material.color = Color.black;
Debug.Log("X pos = "+ gridPos.x + "Y pos = "+ gridPos.y);
}
void OnMouseExit()
{
r.material.color = Color.Lerp(Color.white, Color.white,lerp);
}
}
set a bool type for color like
bool colorchange = false;
public void OnCollisionEnter (Collision col)
{
Debug.Log ("collide");
colorchange = true;
if (colorchange) {
transform.GetComponent<Renderer> ().material.color = Color.red;
}
}