I can't figure out how to change an existing text mesh already in my scene. I have tried to use
void changeScore()
{
TextMesh textObject = GameObject.Find ("scoreText").GetComponent<TextMesh> ();
textObject.text = "test";
}
but it doesn't work. I have been trying multiple different methods to no avail.
The code you posted is correct, which means you're either
not calling changeScore()
getting an error message
changing the TextMesh's text later in the frame before it is rendered
Related
Unity ver. 2019.4.19
Sorry for editing this question several time, I didn't use the term editor and edit mode correctly and I worte the code wrong. Now I've fixed.
I'm using timeline in my project. I made a custom clip like this to change some properties in matrial.
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
GameObject target = GetTargetGameObject();
var renderers = target.GetComponentsInChildren<Renderer>();
foreach (var r in renderers)
{
if (!Application.isPlaying)
{
foreach (var mat in r.sharedMaterials)
{
mat.SetFloat("_SomeProperty", SomeValueChangedByPlaytime(data));
}
}
else
{
// in play mode use r.materials instead
}
}
}
I want to check the effects in timeline while I'm in edit mode, but I don't want to change my material assets by my code.
If I Use
r.sharedMaterials
This will change all matrial assets and this may cause some unexpected effect on unintended objects.
If I Use
r.materials
This will cause error "Instantiating material due to calling renderer.material during edit mode"
So how can I avoid changing matrial asset while still get correct preview in timeline edit mode?
Hi how do we change motion in an AnimatorController using script in Unity Editor?
The red highlight is the one I'd like to change, but using script
My use case is to copy animations from one object, process the animation e.g. adding offset rotation, then add to another object. Since my object has many child objects, I need to create a script to automate this.
Changing the AnimatorController via editor scripts is always quite tricky!
First of all you need to have your AnimationClip from somewhere
// somewhere get the AnimationClip from
var clip = new AnimationClip();
Then you will have to cast the runtimeAnimatorController to an AnimatorController which is only available in the Editor! (put using UnityEditor; at the top of the script!)
var controller = (AnimatorController)animator.runtimeAnimatorController;
Now you can get all its information. In your case you can probably use the default layer (layers[0]) and its stateMachine and according to your image retrieve the defaultState:
var state = controller.layers[0].stateMachine.defaultState;
or find it using Linq FirstOrdefault (put using System.Linq; at the top of the script) like e.g.
var state = controller.layers[0].stateMachine.states.FirstOrDefault(s => s.state.name.Equals("SwimmingAnim")).state;
if (state == null)
{
Debug.LogError("Couldn't get the state!");
return;
}
Finally assign the AnimationClip to this state using SetStateEffectiveMotion
controller.SetStateEffectiveMotion(state, clip);
Note however that even though you can write individual animation curves for an animation clip using SetCurve unfortunately it is not possible to read them properly so it will be very difficult to do what you want
copy animations from one object, process the animation e.g. adding offset rotation, then add to another object.
You will have to go through AnimationUtility.GetCurveBindings which gets quite complex ;)
Good Luck!
I have a Canvas (World Space Render mode) with a Text and a Button component displayed in a tridimensional space (it's a VR app). The canvas instantiated at runtime using a prefab.
I get a reference to the Text object using:
_codeTextLabel = canvasPrefab.transform.Find("CodeTextLabel").gameObject.GetComponent<Text>();
I want to update the text at run-time using:
void Update()
{
_codeTextLabel.text = _codeText;
}
where _codeText is just a variable I update based on specific events.
The problem is that the Text gets updated only the first time, but if I try to change the variable nothing happens. I have tried several combinations and also the method _codeTextLabel.SetAllDirty() but it doesn't work.
The only way to update the text is to re-instantiate the prefab.
Are you instantiating your prefab before setting the values. If you are storing the _codeTextLabel reference before instantiating then your reference will point to the prefab not the runtime object. I can't see the rest of your code, so I can't say for sure. (I would have asked as a comment, but as I'm new I don't have the reputation to do so)
edit: I did a test to try and recreate your problem. I made the following script and it appears to work as expected. CanvasPrefab is a worldspace canvas with a UnityEngine.UI.Text component attached. (The script is attached on an empty game object in the scene btw)
public class ChangeText : MonoBehaviour
{
public GameObject CanvasPrefab;
private GameObject runtimeCanvas;
public string runtimeText = "something";
private Text textRef;
// Start is called before the first frame update
void Start()
{
runtimeCanvas = GameObject.Instantiate(CanvasPrefab);
textRef = runtimeCanvas.GetComponentInChildren<Text>();
}
// Update is called once per frame
void Update()
{
textRef.text = runtimeText;
}
}
as long as you did something wrong, It works absolutely so I guess there are several cases
Failed to do "_codeTextLabel = canvasPrefab.transform.Find("CodeTextLabel").gameObject.GetComponent();"
'_codeTextLabel' lost reference from 'GameObject.
Doesn't change runtimeText' change at all
Subscription of events failed I mean, your updating scripts doesn't get proper event to update that text.
Without codes, this is only thing I can guess for yours so please check above I hope there is case among above.
Edit:
After doing a little more debugging I found that it doesn't work only when I start the game and have the panel/canvas that it sits on disabled. If I have the panel/canvas enabled the whole time then it redraws correctly. However, this obviously isn't a proper solution because I can't show the results before the end of the quiz. I need the panel to be disabled so that I can show it later after the end of the quiz.Is there a reason this is happening? How can I fix this?
End Edit
So I found a script on GitHub that basically creates a UI polygon. It works great in the Editor, however, I want to modify it at runtime. From everything I read all I need to do is call the method SetAllDirty() and it will update the MaskableGraphic and Redraw it. However, whenever I call it, nothing happens. SetVerticesDirty() also did not work. Can someone see where I am going wrong here.
All I am doing is calling DrawPolygon and giving it 4 sides, and passing a float[5] I modified it so that right after I finish setting up my new variables I call SetAllDirty()
Something like this:
public void DrawPolygon(int _sides, float[] _VerticesDistances)
{
sides = _sides;
VerticesDistances = _VerticesDistances;
rotation = 0;
SetAllDirty();
}
Like I said, it works fine in the editor(not runtime), and I am also getting all the values passed to the script correctly(during runtime), but it is not redrawing. As soon as I manipulate something in the inspector it will redraw to the correct shape.
The rest of the script is posted here:
https://github.com/CiaccoDavide/Unity-UI-Polygon/blob/master/UIPolygon.cs
This is the method that I call DrawPolygon from on a Manager script. I see in the log that it prints out the statement, Quiz has ended.
void EndQuiz()
{
Debug.Log("Quiz has ended.");
QuizPanel.SetActive(false);
ResultsPanel.SetActive(true);
float[] Vertices = new float[5] { score1, score2, score3, score4, score1};
resultsPolygon.DrawPolygon(4, Vertices);
}
I got a problem in my project. I want to know that mouse cliked happend on GUI or on any game object.
I have tried this but it is showing null reference exception
EventSystem eventSystem = EventSystem.current;
if (eventSystem.IsPointerOverGameObject())
Debug.Log("left click over a gui element");
how to detect?? Is there any event available or else?
IsPointerOverGameObject() is fairly broken on mobile and some corner cases. We rolled our own for our project and it works like a champ on all platforms we've thrown it at.
private bool IsPointerOverUIObject() {
PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current);
eventDataCurrentPosition.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(eventDataCurrentPosition, results);
return results.Count > 0;
}
Source:
http://forum.unity3d.com/threads/ispointerovereventsystemobject-always-returns-false-on-mobile.265372/
There is some approaches that you can use to detect if your mouse is over a legacy GUI element here I'll show you one that I hope will work fine for you, if not research a little about "mouse over GUI" and you'll find a lot of different ways to do it (this one is what I use on my legacy GUI projects and usually works fine with touch):
Create an easily accessible behaviour (usually a singleton) to hold your MouseOverGUI "status":
if you are using GUILayout.Button you need to catch the last drawn rect, if you are GUI.Button just use the same rect you passed as button's param like this:
// GUILayout
( Event.current.type == EventType.Repaint &&
GUILayoutUtility.GetLastRect().Contains( Event.current.mousePosition ) ) {
mouseOverGUI = true;
}
} // you need call it in your OnGUI right after the call to the element that you want to control
// GUI
( Event.current.isMouse &&
yourRect.Contains( Event.current.mousePosition ) ) {
mouseOverGUI = true;
}
}
after that you just need to test if your mouseOverGUI is true or false to allow or not your desired click actions before execute them. (a good understanding of unity loops will help you to catch and test the flag in correct timing to avoid problems expecting to get something that already changed)
edited: also remember to reset mouseOverGUI to false when it is not over GUI ;)
Finally got my answer here:
There are three ways to do this, as demonstrated in this video tutorial. this video save me:).
Use EventSystem.current.IsPointerOverGameObject
Convert your OnMouseXXX and Raycasts to an EventSystem trigger. Use a physics raycaster on the camera
Implement the various handler interfaces from the EventSystems namespace. Use a physics raycaster on the camera.