hi im trying to make a system where a variable controls the position of an object so that if the variable goes up then the Y position of the object will go up and if the variable goes down then the Y position of the object will go down.
I am trying to control the variable from a separate script but the value of the variable is not changing.
the variable script:
public class Money : MonoBehaviour {
public static float Flow;
public static float FlowPos;
// Use this for initialization
void Start () {
Flow = 50;
}
// Update is called once per frame
void Update () {
FlowPos = Flow/100;
print(Flow);
transform.position = new Vector3(10.56f,12 + FlowPos,1);
}
the script trying to change the variable:
using UnityEngine;
using System.Collections;
public class Barista01 : MonoBehaviour {
bool dragging = false;
bool CardActive = true;
void Start(){
}
void Update(){
if (transform.position.x > 11.5f && dragging == false){
GameControllerScript.Active = false;
this.Destroy(gameObject);
}
else if (transform.position.x < 4.5f && dragging == false){
GameControllerScript.Active = false;
Worker.Morale += 20;
Money.Flow -= 15;
this.Destroy(gameObject);
}
if (GameControllerScript.CardCall == 2 && CardActive == true){
CardActive = false;
Worker.Morale -= 20;
transform.position = new Vector3(8f, 6.89f, 9f);
}
}
void OnMouseDown(){
{
dragging = true;
}
}
void OnMouseUp(){
{
dragging = false;
}
}
}
edit: I put the plus, minus and eaquals symbols in the correct positions however the variables still do not change
You should correct these two lines:
Worker.Morale =+ 20;
Money.Flow =- 15;
to
Worker.Morale += 20;
Money.Flow -= 15;
Related
I am working on a flocking system in Unity and am new to c#. I am working with 2 scripts - 1 that manages the overall flock (FlockTest) and the other that manages particle behaviour (FlockParticleBehaviour). I have followed a tutorial which has public boolean values that control seeking behaviour in FlockParticleBehaviour through FlockTest. In play mode, I can toggle these booleans to change the goal seeking behaviour. However, I want to automate this toggling based on time (To add it to an AR session). I have added an if statement to void Update() in the FlockTest and when I hit play, the seekGoal and obedient boolean boxes switch on and off but nothing happens to the particles. I have tried using an invoke method which didn't work(no errors but boxes dont switch on and off) and thought about trying a coRoutine but I am not sure this will work since I don't want to stop and start my script. I am at a loss as to how to get the particles obeying the boolean in update. Am I meant to be referencing in my particle behaviour script's flock function? Very new so would love some help if anyone knows a better way forward!
FlockTest script (contains if statement)
using System.Collections.Generic;
using UnityEngine;
public class FlockTest : MonoBehaviour
{
public GameObject[] particles;
public GameObject particlePrefab;
public int particleCount = 10;
public Vector3 range = new Vector3(5,5,5);
public Vector3 innerLimit = new Vector3(1,1,1);
public bool seekGoal = true;
public bool obedient = true;
public bool willful = false;
[Range(0, 200)]
public int neighbourDistance =50;
[Range(0,2)]
public float maxForce = 0.5f;
[Range(0,5)]
public float maxvelocity = 2.0f;
// Start is called before the first frame update
void Start()
{
int time = (int)Time.time;
particles = new GameObject[particleCount];
for(int i = 0; i < particleCount; i++)
{
Vector3 particlePos = new Vector3(Random.Range(-range.x, range.x), Random.Range(-range.y, range.y), Random.Range(-range.z, range.z));
particles[i] = Instantiate(particlePrefab, this.transform.position + particlePos, Quaternion.identity) as GameObject;
particles[i].GetComponent<FlockParticleBehaviour>().manager = this.gameObject;
}
}
void Update()
// the toggles in the inspector are changing but nothing is happening with the particles.
{
int time = (int)Time.time;
if(time == 3f) {
seekGoal = false;
obedient = false;
willful = true;
}
if(time == 6f)
{
seekGoal = true;
obedient = true;
willful = false;
}
}
}
FlockParticleBehaviour script
using System.Collections.Generic;
using UnityEngine;
public class FlockParticleBehaviour : MonoBehaviour
{
public GameObject manager;
public Vector3 location = Vector3.zero;
public Vector3 velocity;
Vector3 goalPos = Vector3.zero;
Vector3 currentForce; //this is a current force position. pushes particle around by adding all the other forces
// Start is called before the first frame update
void Start()
{
velocity = new Vector3(Random.Range(0.01f, 0.1f), Random.Range(0.01f, 0.1f), Random.Range(0.01f, 0.1f));
location = new Vector3(this.gameObject.transform.position.x, this.gameObject.transform.position.y, this.gameObject.transform.position.z);
}
Vector3 seek(Vector3 target)
{
return(target - location);
}
void applyForce(Vector3 f)
{
Vector3 force = new Vector3(f.x, f.y, f.z);
if(force.magnitude > manager.GetComponent<FlockTest>().maxForce)
{
force = force.normalized;
force *= manager.GetComponent<FlockTest>().maxForce;
}
this.GetComponent<Rigidbody>().AddForce(force);
if(this.GetComponent<Rigidbody>().velocity.magnitude > manager.GetComponent<FlockTest>().maxvelocity)
{
this.GetComponent<Rigidbody>().velocity = this.GetComponent<Rigidbody>().velocity.normalized;
this.GetComponent<Rigidbody>().velocity *= manager.GetComponent<FlockTest>().maxvelocity;
}
Debug.DrawRay(this.transform.position, force, Color.white);
}
Vector3 align()
{
float neighbourdist = manager.GetComponent<FlockTest>().neighbourDistance;
Vector3 sum = Vector3.zero;
int count = 0;
foreach (GameObject other in manager.GetComponent<FlockTest>().particles)
{
if(other == this.gameObject) continue;
float d = Vector3.Distance(location, other.GetComponent<FlockParticleBehaviour>().location);
if (d < neighbourdist) {
sum += other.GetComponent<FlockParticleBehaviour>().velocity;
count++;
}
}
if (count >0)
{
sum /= count;
Vector3 steer = sum - velocity;
return steer;
}
return Vector3.zero;
}
Vector3 cohesion()
{
float neighbourdist = manager.GetComponent<FlockTest>().neighbourDistance;
Vector3 sum = Vector3.zero;
int count = 0;
foreach (GameObject other in manager.GetComponent<FlockTest>().particles)
{
if(other == this.gameObject) continue;
float d = Vector3.Distance(location, other.GetComponent<FlockParticleBehaviour>().location);
if(d < neighbourdist)
{
sum += other.GetComponent<FlockParticleBehaviour>().location;
count++;
}
}
if (count > 0)
{
sum /= count;
return seek(sum);
}
return Vector3.zero;
}
void flock()
{
location = this.transform.position;
velocity = this.GetComponent<Rigidbody>().velocity;
if(manager.GetComponent<FlockTest>().obedient && Random.Range(0,50) <=1)
{
Vector3 ali = align();
Vector3 coh = cohesion();
Vector3 gl;
if(manager.GetComponent<FlockTest>().seekGoal)
{
gl = seek(goalPos);
currentForce = gl + ali +coh;
}
else
currentForce = ali + coh;
currentForce = currentForce.normalized;
}
if(manager.GetComponent<FlockTest>().willful && Random.Range(0,50)<=1)
{
if(Random.Range(0,50)<1) //change direction
currentForce = new Vector3(Random.Range(0.01f, 0.1f), Random.Range(0.01f, 0.1f),Random.Range(0.01f, 0.1f));
}
applyForce(currentForce);
}
// Update is called once per frame
void Update()
{
flock();
goalPos = manager.transform.position;
}
}
Several points:
it is much easier and cleaner to set your flock manager directly as FlockTest, not GameObject to avoid GetComponent calls.
I cannot understand what you want to achieve by calling (int)Time.time and comparing it later with 3 and 6. Time.time returns the number of seconds that passed from the start of the application. So your code in Update method of FlockTest script will not have any chance to be called after the seventh second of your game passed. So obedient will always be true and willful will always be false after the seventh second.
Your Random.Range(0, 50) <= 1 is quite a low chance. It will return an int value from 0 to 49, so it is only a 2% chance that your changes in FlockTest will apply to FlockParticleBehaviour instance. Is it what you wanted to get? You can try to remove this random from the if statement to make this chance 100% and check if this is an issue.
Right now it seems like the chance of changing something is too low to see it in several seconds of the game. As I've said above, after the seventh second your bool values will never change.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class MoveOnCurvedLines : MonoBehaviour
{
public LineRenderer lineRenderer;
public List<GameObject> objectsToMove = new List<GameObject>();
public float speed;
public bool go = false;
public bool moveToFirstPositionOnStart = false;
private Vector3[] positions;
private Vector3[] pos;
private int index = 0;
private bool goForward = true;
private List<GameObject> objectsToMoveCopy = new List<GameObject>();
// Start is called before the first frame update
void Start()
{
objectsToMove = GameObject.FindGameObjectsWithTag("New Prefab").ToList();
pos = GetLinePointsInWorldSpace();
if (moveToFirstPositionOnStart == true)
{
for (int i = 0; i < objectsToMove.Count; i++)
{
objectsToMove[i].transform.position = pos[index];
}
}
StartCoroutine(AddNew());
}
Vector3[] GetLinePointsInWorldSpace()
{
positions = new Vector3[lineRenderer.positionCount];
//Get the positions which are shown in the inspector
lineRenderer.GetPositions(positions);
//the points returned are in world space
return positions;
}
// Update is called once per frame
void Update()
{
if (go == true)
{
Move();
}
}
void Move()
{
for (int i = 0; i < objectsToMoveCopy.Count; i++)
{
Vector3 newPos = objectsToMoveCopy[i].transform.position;
float distanceToTravel = speed * Time.deltaTime;
bool stillTraveling = true;
while (stillTraveling)
{
Vector3 oldPos = newPos;
newPos = Vector3.MoveTowards(oldPos, pos[index], distanceToTravel);
distanceToTravel -= Vector3.Distance(newPos, oldPos);
if (newPos == pos[index]) // Vector3 comparison is approximate so this is ok
{
// when you hit a waypoint:
if (goForward)
{
bool atLastOne = index >= pos.Length - 1;
if (!atLastOne) index++;
else { index--; goForward = false; }
}
else
{ // going backwards:
bool atFirstOne = index <= 0;
if (!atFirstOne) index--;
else { index++; goForward = true; }
}
}
else
{
stillTraveling = false;
}
}
objectsToMoveCopy[i].transform.position = newPos;
}
}
IEnumerator AddNew()
{
WaitForSeconds waitThreeSeconds = new WaitForSeconds(3);
foreach (var objToMove in objectsToMove)
{
yield return waitThreeSeconds;
objectsToMoveCopy.Add(objToMove);
}
}
}
I'm using StartCoroutine and the method AddNew to move each object between the waypoints every 3 seconds.
The logic :
First object to move from the List is start moving from the first position.
After 3 seconds the second object to move from the List is start moving from the first position.
The goal is to make that each object will start moving from the first position after 3 seconds following the first moving object before him so in the end I will have the objects moving with spoaces of 3 seconds between them.
The problem :
The first object is start moving after 3 seconds from the first position then the second and third and the resto f objects are start moving but from the last moved object and the other objects that already move are get merged with the other objects in the end I have a group of all the objects to move are moving together.
The same behave I want to be if they are moving in reverse.
Your objects merge, since you only have one index for the objects' target position, meaning all objects move towards the same point, not each object towards it's respective next point on the path. This results in a merge as soon as the first object turns around and runs backwards.
It would be best to split your logic into two classes, since otherwise you'd have to keep track of every object's path separately, meaning you need an int[] indices for the current target position of each object, another array for the goForward bools and so on for every new property you introduce.
Controller:
public class MovementController : MonoBehaviour
{
[SerializeField]
private LineRenderer lineRenderer;
[SerializeField]
private float speed;
[SerializeField]
private bool moveToFirstPositionOnStart;
public List<MoveOnCurvedLines> movingObjects = new List<MoveOnCurvedLines>();
void Start()
{
Vector3[] positions = GetPositions();
movingObjects = GameObject.FindGameObjectsWithTag("New Prefab").Select(go => go.GetComponent<MoveOnCurvedLines>().ToList();
foreach (MoveOnCurvedLines obj in movingObjects)
{
obj.Init(positions, speed, moveToFirstPositionOnStart);
}
StartCoroutine(TriggerObjects(false));
}
Vector3[] GetPositions()
{
Vector3[] positions = new Vector3[lineRenderer.positionCount];
//Get the positions which are shown in the inspector
lineRenderer.GetPositions(positions);
return positions;
}
IEnumerator TriggerObjects(bool delayFirstObject)
{
WaitForSeconds waitThreeSeconds = new WaitForSeconds(3);
if (delayFirstObject)
yield return waitThreeSeconds;
foreach (MoveOnCurvedLines obj in movingObjects)
{
obj.StartMoving();
yield return waitThreeSeconds;
}
}
}
Movement logic:
public class MoveOnCurvedLines : MonoBehaviour
{
private Transform myTransform;
private bool initialized;
private Vector3[] pos;
private int posIndex = 0;
private float speed;
private bool goForward = true;
private Coroutine moving;
public void Init(Vector3[] positions, float speed, bool instantlyMoveToFirstPosition)
{
myTransform = transform;
pos = positions;
this.speed = speed;
if (instantlyMoveToFirstPosition)
myTransform.position = positions[0];
initialized = true;
}
public void StartMoving()
{
if (initialized && moving == null)
moving = StartCoroutine(Move());
}
public void StopMoving()
{
if (moving != null)
{
StopCoroutine(moving);
moving = null;
}
}
private IEnumerator Move()
{
while (true)
{
Vector3 newPos = myTransform.position;
float distanceToTravel = speed * Time.deltaTime;
bool stillTraveling = true;
while (stillTraveling)
{
Vector3 oldPos = newPos;
newPos = Vector3.MoveTowards(oldPos, pos[posIndex], distanceToTravel);
distanceToTravel -= Vector3.Distance(newPos, oldPos);
if (newPos == pos[posIndex]) // Vector3 comparison is approximate so this is ok
{
// when you hit a waypoint:
if (goForward)
{
bool atLastOne = posIndex >= pos.Length - 1;
if (!atLastOne)
{
posIndex++;
}
else
{
posIndex--;
goForward = false;
}
}
else
{ // going backwards:
bool atFirstOne = posIndex <= 0;
if (!atFirstOne)
{
posIndex--;
}
else
{
posIndex++;
goForward = true;
}
}
}
else
{
stillTraveling = false;
}
}
myTransform.position = newPos;
}
}
}
MovementController only provides the necessary data, which all your objects share (e.g. the path), but every MoveOnCurvedLines object keeps track of it's progress independently.
Optimizations:
I cached transform in myTransform, since Unity's transform calls GetComponent<Transform>() every time producing unnecessary overhead.
Moving is done in a coroutine, not in Update, since checking n go bools every frame n objects do not move is unnecessary.
I changed your public fields to private ones getting serialized, since it's best practice to restrict access as much as possible. If you need to access them from another script in your project just make them public again.
Im using Unity and have asked this on there forums however have not had any replies. Ive found this example from a plugin where I am trying to use the kinect to rotate an object using my right hand to rotate it right and the left to rotate left. I have managed to get the object to do this apart from it stops at each side of the object, but cant work out what part of the code is doing this.
Thanks
using UnityEngine;
using System.Collections;
using System;
public class GestureListener : MonoBehaviour, KinectGestures.GestureListenerInterface
{
// GUI Text to display the gesture messages.
public GUIText GestureInfo;
private bool raiselefthand;
private bool raiserighthand;
public bool IsSwipeLeft()
{
if(raiserighthand)
{
raiserighthand = false;
return true;
}
return false;
}
public bool IsSwipeRight()
{
if(raiselefthand)
{
raiselefthand = false;
return true;
}
return false;
}
public void UserDetected(uint userId, int userIndex)
{
// detect these user specific gestures
KinectManager manager = KinectManager.Instance;
manager.DetectGesture(userId, KinectGestures.Gestures.RaiseLeftHand);
manager.DetectGesture(userId, KinectGestures.Gestures.RaiseRightHand);
if(GestureInfo != null)
{
GestureInfo.GetComponent<GUIText>().text = "Swipe left or right to change the slides.";
}
}
public void UserLost(uint userId, int userIndex)
{
if(GestureInfo != null)
{
GestureInfo.GetComponent<GUIText>().text = string.Empty;
}
}
public void GestureInProgress(uint userId, int userIndex, KinectGestures.Gestures gesture,
float progress, KinectWrapper.NuiSkeletonPositionIndex joint, Vector3 screenPos)
{
// don't do anything here
}
public bool GestureCompleted (uint userId, int userIndex, KinectGestures.Gestures gesture,
KinectWrapper.NuiSkeletonPositionIndex joint, Vector3 screenPos)
{
string sGestureText = gesture + " detected";
if(GestureInfo != null)
{
GestureInfo.GetComponent<GUIText>().text = sGestureText;
}
if(gesture == KinectGestures.Gestures.RaiseRightHand)
raiserighthand = true;
else if(gesture == KinectGestures.Gestures.RaiseLeftHand)
raiselefthand = true;
return true;
}
public bool GestureCancelled (uint userId, int userIndex, KinectGestures.Gestures gesture,
KinectWrapper.NuiSkeletonPositionIndex joint)
{
// don't do anything here, just reset the gesture state
return true;
}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PresentationScript : MonoBehaviour
{
public bool slideChangeWithGestures = true;
public bool slideChangeWithKeys = true;
public float spinSpeed = 5;
public bool autoChangeAlfterDelay = false;
public float slideChangeAfterDelay = 10;
public List<Texture> slideTextures;
public List<GameObject> horizontalSides;
// if the presentation cube is behind the user (true) or in front of the user (false)
public bool isBehindUser = false;
private int maxSides = 0;
private int maxTextures = 0;
private int side = 0;
private int tex = 0;
private bool isSpinning = false;
private float slideWaitUntil;
private Quaternion targetRotation;
private GestureListener gestureListener;
void Start()
{
// hide mouse cursor
Cursor.visible = false;
// calculate max slides and textures
maxSides = horizontalSides.Count;
maxTextures = slideTextures.Count;
// delay the first slide
slideWaitUntil = Time.realtimeSinceStartup + slideChangeAfterDelay;
targetRotation = transform.rotation;
isSpinning = false;
tex = 0;
side = 0;
if(horizontalSides[side] && horizontalSides[side].GetComponent<Renderer>())
{
horizontalSides[side].GetComponent<Renderer>().material.mainTexture = slideTextures[tex];
}
// get the gestures listener
gestureListener = Camera.main.GetComponent<GestureListener>();
}
void Update()
{
// dont run Update() if there is no user
KinectManager kinectManager = KinectManager.Instance;
if(autoChangeAlfterDelay && (!kinectManager || !kinectManager.IsInitialized() || !kinectManager.IsUserDetected()))
return;
if(!isSpinning)
{
if(slideChangeWithKeys)
{
if(Input.GetKeyDown(KeyCode.PageDown))
RotateToNext();
else if(Input.GetKeyDown(KeyCode.PageUp))
RotateToPrevious();
}
if(slideChangeWithGestures && gestureListener)
{
if(gestureListener.IsSwipeLeft())
RotateToNext();
else if(gestureListener.IsSwipeRight())
RotateToPrevious();
}
// check for automatic slide-change after a given delay time
if(autoChangeAlfterDelay && Time.realtimeSinceStartup >= slideWaitUntil)
{
RotateToNext();
}
}
else
{
// spin the presentation
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, spinSpeed * Time.deltaTime);
// check if transform reaches the target rotation. If yes - stop spinning
float deltaTargetX = Mathf.Abs(targetRotation.eulerAngles.x - transform.rotation.eulerAngles.x);
float deltaTargetY = Mathf.Abs(targetRotation.eulerAngles.y - transform.rotation.eulerAngles.y);
if(deltaTargetX < 1f && deltaTargetY < 1f)
{
// delay the slide
slideWaitUntil = Time.realtimeSinceStartup + slideChangeAfterDelay;
isSpinning = false;
}
}
}
private void RotateToNext()
{
// set the next texture slide
tex = (tex + 1) % maxTextures;
if(!isBehindUser)
{
side = (side + 1) % maxSides;
}
else
{
if(side <= 0)
side = maxSides - 1;
else
side -= 1;
}
if(horizontalSides[side] && horizontalSides[side].GetComponent<Renderer>())
{
horizontalSides[side].GetComponent<Renderer>().material.mainTexture = slideTextures[tex];
}
// rotate the presentation
float yawRotation = !isBehindUser ? 360f / maxSides : -360f / maxSides;
Vector3 rotateDegrees = new Vector3(0f, yawRotation, 0f);
targetRotation *= Quaternion.Euler(rotateDegrees);
isSpinning = true;
}
private void RotateToPrevious()
{
// set the previous texture slide
if(tex <= 0)
tex = maxTextures - 1;
else
tex -= 1;
if(!isBehindUser)
{
if(side <= 0)
side = maxSides - 1;
else
side -= 1;
}
else
{
side = (side + 1) % maxSides;
}
if(horizontalSides[side] && horizontalSides[side].GetComponent<Renderer>())
{
horizontalSides[side].GetComponent<Renderer>().material.mainTexture = slideTextures[tex];
}
// rotate the presentation
float yawRotation = !isBehindUser ? -360f / maxSides : 360f / maxSides;
Vector3 rotateDegrees = new Vector3(0f, yawRotation, 0f);
targetRotation *= Quaternion.Euler(rotateDegrees);
isSpinning = true;
}
}
I have managed to get the object to do this apart from it stops at each side of the object, but cant work out what part of the code is doing this.
I understand you ask for help finding which parts are involved in the rotation.
As such, I looked through the scripts and noticed 2 sections in the PresentationScript.
This part in the Update() method. Based on the code and the comments that are part of it.
// spin the presentation
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, spinSpeed * Time.deltaTime);
// check if transform reaches the target rotation. If yes - stop spinning
float deltaTargetX = Mathf.Abs(targetRotation.eulerAngles.x - transform.rotation.eulerAngles.x);
float deltaTargetY = Mathf.Abs(targetRotation.eulerAngles.y - transform.rotation.eulerAngles.y);
if(deltaTargetX < 1f && deltaTargetY < 1f)
{
// delay the slide
slideWaitUntil = Time.realtimeSinceStartup + slideChangeAfterDelay;
isSpinning = false;
}
This line in the Start() method is also involved.
targetRotation = transform.rotation;
A transform controls the position, scaling and as is relevant for this case, also the rotation of an object.
I am a bit of a noob to programming and I am trying to make a GameObject , deactivate and reactivate over a set amount of seconds.For example I want my star to slowly blink before it goes away, to create a cool looking effect. If there is a better way of using this method done with out using SetActive(false) and what not , please feel free to give me your method - This is my code , Sorry if its messy i gotta get better at this but i will in due time
Thanks guys
//Timers
public float ScoreTimer;
public float[] TimeMarkStamp;
//Scoring
public int totalCollStars;
[Space]
public int maxStars = 5;
public GameObject[] StarImages;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
ScoreTimer += Time.deltaTime;
if (ScoreTimer <= TimeMarkStamp[0])
{
Debug.Log("It works");
StarImages[0].SetActive(false);
}
else if (ScoreTimer <= TimeMarkStamp[1])
{
Debug.Log("It workds" + TimeMarkStamp[1]);
StarImages[1].SetActive(false);
}
else if (ScoreTimer <= TimeMarkStamp[2])
{
Debug.Log("It works" + TimeMarkStamp[2]);
StarImages[2].SetActive(false);
}
else if (ScoreTimer <= TimeMarkStamp[3])
{
//This is not working
InvokeRepeating("flickerEffect", 3f, 1f);
}
}
void flickerEffect()
{
bool flickCheck = false;
if (flickCheck == false)
{
StarImages[3].SetActive(true);
flickCheck = true;
}
else if (flickCheck == true)
{
StarImages[3].SetActive(false);
flickCheck = false;
}
}
}
If there is a better way of using this method done with out using
SetActive(false) and what not
Yes, there is a better way, other than using the SetActive function. You should change the alpha color of the GameObject from 0 to 1 back and forth. After that you can then disable the GameObject with SetActive. This saves how much garbage would have been generated when repeatedly calling the SetActive function.
If this is a 3D GameObject, change the Rendering Mode from Opaque(default) to Fade or Transparent.
A simple function that can do this:
void blink(GameObject obj, float blinkSpeed, float duration)
{
StartCoroutine(_blinkCOR(obj, blinkSpeed, duration));
}
IEnumerator _blinkCOR(GameObject obj, float blinkSpeed, float duration)
{
obj.SetActive(true);
Color defualtColor = obj.GetComponent<MeshRenderer>().material.color;
float counter = 0;
float innerCounter = 0;
bool visible = false;
while (counter < duration)
{
counter += Time.deltaTime;
innerCounter += Time.deltaTime;
//Toggle and reset if innerCounter > blinkSpeed
if (innerCounter > blinkSpeed)
{
visible = !visible;
innerCounter = 0f;
}
if (visible)
{
//Show
show(obj);
}
else
{
//Hide
hide(obj);
}
//Wait for a frame
yield return null;
}
//Done Blinking, Restore default color then Disable the GameObject
obj.GetComponent<MeshRenderer>().material.color = defualtColor;
obj.SetActive(false);
}
void show(GameObject obj)
{
Color currentColor = obj.GetComponent<MeshRenderer>().material.color;
currentColor.a = 1;
obj.GetComponent<MeshRenderer>().material.color = currentColor;
}
void hide(GameObject obj)
{
Color currentColor = obj.GetComponent<MeshRenderer>().material.color;
currentColor.a = 0;
obj.GetComponent<MeshRenderer>().material.color = currentColor;
}
Usage:
void Start()
{
blink(gameObject, 0.2f, 5f);
}
If this is a SpriteRender, you have to replace all the obj.GetComponent<MeshRenderer>().material.color code with obj.GetComponent<SpriteRenderer>().color.
I am trying to set a Slider value through C# code.
I have a Main.scene which includes a slider called Slider.
The main camera has a game manager script attached to it.
The slider is not Interactable (so I can display the value but the user can't change it).
I defined a variable:
[SerializeField] private Slider sliderObj;
and put my slider in the inspector in this field
I have a float s variable that I want to reflect in the slider:
s = player1Time / (player1Time + player2Time) * 100.0f;
but when I write:
sliderObj.value = s;
I see this error:
'Slider' does not contain a definition for 'value' and no extension method 'value' accepting a first argument of type 'Slider' could be found (are you missing a using directive or an assembly reference?) [Assembly-CSharp]
any ideas?
Here is the entire script:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public static GameManager instance = null; //this is to create a singleton => only one instance of this script running in memory
//so we only have one Game Manager running on memory
private int activePlayer = 1; //1 = down position 2 = up position
[SerializeField]
private GameObject playerObj;
[SerializeField]
private Text timer1Text; //player1 timer text
[SerializeField]
private Text timer2Text; //player2 timer text
[SerializeField]
private GameObject startBtn;
[SerializeField]
private Texture stopTexture;
[SerializeField]
private Slider sliderObj;
private Slider sli;
public float sli_val;
private RawImage img;
private float startTime;
private bool player1Active = true;
private static float player1Time;
private static float lastP1Time;
private static float player2Time;
private static float lastP2Time;
private bool gameOver = false;
private bool gameStarted = false;
private bool gameFinished = false;
void Awake()
{
if (instance == null)
{ //check if an instance of Game Manager is created
instance = this; //if not create one
}
else if (instance != this)
{
Destroy(gameObject); //if already exists destroy the new one trying to be created
}
DontDestroyOnLoad(gameObject); //Unity function allows a game object to persist between scenes
}
public bool GameStarted
{
get { return gameStarted; }
}
public bool GameOver
{
get { return gameOver; }
}
public void StartGame()
{
if (!gameStarted)
{
gameStarted = true;
//startTime = Time.time;
//player1Time = startTime;
player1Active = true;
//select start button
img = (RawImage)startBtn.GetComponent<RawImage>();
//replace it with stop button
img.texture = (Texture)stopTexture;
}
else
{
gameStarted = false;
gameOver = true;
}
Debug.Log("StartGame");
}
public void ChangePlayer()
{
float ty = 0f;
int smileyRotate = 180;
int sliderRotate = 180;
Quaternion smileyRotation = playerObj.transform.localRotation;
ty = playerObj.transform.position.y * -1;
if (activePlayer == 1)
{
player1Active = false;
activePlayer = 2;
smileyRotate = 180;
}
else
{
player1Active = true;
activePlayer = 1;
smileyRotate = 0;
}
playerObj.transform.position = new Vector2(playerObj.transform.position.x, ty);
smileyRotation.x = smileyRotate;
playerObj.transform.localRotation = smileyRotation;
}
// Use this for initialization
void Start()
{
}
// Update is called once per frame
private string FormatTime(float pt)
{
string hours, minutes, seconds, shaon;
hours = ((int)pt / 3600).ToString("00");
minutes = ((int)pt / 60).ToString("00");
seconds = (pt % 60).ToString("00");
if ((pt / 3600) > 1)
{
shaon = string.Format("{0:D1}:{1:D2}:{2:D2}", hours, minutes, seconds);
}
else
{
shaon = string.Format("{0:D2}:{1:D2}", minutes, seconds);
}
return shaon;
}
void Update()
{
float s;
GameObject sl1 = GameObject.Find("Slider");
if (GameStarted)
{
string zman;
if (player1Active)
{
player1Time += Time.deltaTime; //if player 1 active update his time
zman = FormatTime(player1Time);
timer1Text.text = zman;
//Debug.Log("player2Time: : "+ player2Time);
}
else
{
player2Time += Time.deltaTime; //if player 2 active update his time
zman = FormatTime(player2Time);
timer2Text.text = zman;
Debug.Log("player1Time: : " + player1Time);
}
s = player1Time / (player1Time + player2Time) * 100.0f;
//sliderObj.GetComponent<Slider>;
//sliderObj.=0.5f;
sli = GameObject.Find("Slider").GetComponent<Slider>();
sli.value = s;
sliderObj.value = s;
}
}
}
First of all, thanks for all your help.
Specially to bpgeck that chat with me and help me a lot.
Also Programmer was correct.
The main problem I had was the fatal error of calling the script attached to my slider Slider (I am still a noob, but learning)
I deleted that script and created a new one called Slider Percentage, in it I use the update function to change the value of the slider:
GameObject temp;
// Use this for initialization
void Start () {
temp = GameObject.Find("Slider");
}
// Update is called once per frame
void Update () {
temp.GetComponent<Slider>().value = GameManager.instance.GetPercentage;
}
The percentage value is still being calculated in the GameManager, but it is displayed using this script.
Now all works!! Thanks again for all your help :-)