A simple task. I have a ScoreController which will set the score to UI. I have a UI label that has ScoreView in it
The question is how do I get this ScoreView in my controller
I have found out the way to get View from prefab that's being instantiated:
public class CellViewFactory : ICellViewFactory
{
public ICellView GetView(Vector3 position)
{
var prefab = Resources.Load<GameObject>("Cell");
var instance = UnityEngine.Object.Instantiate(prefab);
var cellView = instance.GetComponent<ICellView>();
cellView.SetPosition(position);
return cellView;
}
}
But since UI isn't instantiated by the code, what's the way to get the ScoreView from it?
Now, I have found an option to call a static method of a Factory and pass self to the method. Smth like this:
public class ScoreView : MonoBehaviour
{
void Start()
{
ScoreViewFactory.NotifyScoreViewCreated(this);
}
}
But it doesn't seem to be flexible using static methods in decoupled code with Factories and interfaces. Hope there's another way
I would also be glad if you post some complete tutorioal on MVC in Unity. Seems that there's no complete working tutorials.
It would also be great if you would share an example of MVC pattern in Unity using DependencyInjection.
Related
I need to setup my button components in Unity to look like this via C# (i.e. with "Transition" and "Navigation" set to "None").
For the Navigation, it was a little unintuitive but I eventually found that this worked:
Navigation customNav = new Navigation();
customNav.mode = Navigation.Mode.None;
myButton.navigation = customNav;
But I can't for the life of me find a equivalent for "Transition". If it's in the documentation, it must be buried under a heading I can't find. Does anyone have any idea how it can be done?
You can change the transition value by assigning a Selectable.Transition type enum value to the .transition property.
Example
using UnityEngine;
using UnityEngine.UI;
public class TestScript : MonoBehaviour
{
[SerializeField]
private Button target = null;
private void Start()
{
target.transition = Selectable.Transition.None;
}
}
Reference
https://docs.unity3d.com/2017.3/Documentation/ScriptReference/UI.Selectable-transition.html
I have an issue with my In App Purchases manager. I load my scene and can successfully purchase items. I go to a new scene in game and then back to that scene and now it says...
`MissingReferenceException: The object of type 'IAPManager' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.`and then points my to this line
moneyController = GetComponent<MoneyController>();
Why does it crash at that point? Do I need to add DontDestroyOnLoad or something? I'm not familiar with that or how to use it though. Am I missing something simple?
Here are some more code snippets that may or may not prove useful. This code is from a tutorial hence why it's difficult for me to pin point the issue.
public static IAPManager Instance{set;get;}
private void Awake() {
Instance = this;
}
you have to put in DontDestroyOnLoad this way you will not get any error for same. below is the code that you can use.
private static IAPManager instance;
public static IAPManager Instance
{
get
{
if (instance == null)
{
GameObject o = new GameObject ("IAPManager");
instance=o.AddComponent<IAPManager>();
DontDestroyOnLoad (o);
}
return instance;
}
}
I am making games using Unity and I have some problems and I will ask questions.
The animator of an object instantiated using a prefab does not work properly, and precisely a specific event is a problem. The object placed in the hierarchy is fine. However, certain events do not work for objects instantiated using a script.
this is code.
public Animator guestmove;
public void Jump_motion()
{
if (tag == "Boy")
{
guestmove.SetTrigger("Jump");
}
}
public void Angry_motion()
{
guestmove.SetTrigger("Angry");
}
Here, we implement the event by pressing a button.
I changed the code to work when the tags match, but the objects I placed in the hierarchy also do not work.
This is the code that creates the instance.
if (currentlyObject > 0){
boyObject = Instantiate(boy, tableObject.transform.position, tableObject.transform.rotation);
boyObject.transform.Translate(new Vector3(0, -3, -11));
girlObject = Instantiate(girl, tableObject.transform.position, tableObject.transform.rotation);
girlObject.transform.Translate(new Vector3(1.5f, -3, -11));
}
I kept searching for the relevant data, but I could not find any cases of similar problems. I do not know where the problem is, please help me.
this is link
(https://drive.google.com/file/d/1SKbSIfFQM4-n8l-ZBBvZb_3SuNx-kd5-/view?usp=sharing)
Use the transition to triggers from Any State, this should work.
And where are your functions called?
I was coding a very simple program that lets you move around a circle, with also a rectangle in the stage. I wanted to make the circle get in front of the rectangle while you are dragging it, but when you released the mouse, the circle would be sent back.
I don't know how to set a public variable using the getChildIndex method. I don't really care about the rest of the code. I'm mainly interested in how can I make the getChildIndex method work with a public variable.
package code
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.Sprite;
public class Main extends MovieClip
{
public var myCircleIndex:int = getChildIndex(myCircle);
public function Main()
{
myCircle.addEventListener(MouseEvent.MOUSE_DOWN, mouseClicking);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseReleased);
}
public function mouseClicking(e:MouseEvent): void
{
myCircle.startDrag();
setChildIndex(myCircle, numChildren-1);
}
public function mouseReleased(e:MouseEvent): void
{
myCircle.stopDrag();
setChildIndex(myCircle, myCircleIndex);
}
}
}
I'm using an instance ("myCircle") that I created directly in the stage as a movie clip.
The problem is in the public var I set at the beginning, it doesn't let me get the child index of myCircle, but if I put the same line inside a function, it works.
I know I could directly put the index number of myCircle in the last line (and erasing the public var myCircleIndex), but I figured out that there would be a way of using the getChildIndex for a public var in a class.
How do you use getChildIndex in a public variable inside a class?
The reason it doesn't work, is because your timeline objects don't yet exist when the line public var myCircleIndex:int runs.
You shouldn't try and access non-primitive objects in your class level variable declarations for this very reason, as nothing else in the class is available yet when those vars are created.
Here is how you can refactor this (see the code comments):
public class Main extends MovieClip
{
public var myCircleIndex:int; //just create the reference here, don't assign it
public var myCircle:flash.display.DisplayObject; //this line is just for better compile time checking and code completion, completely optional
public function Main()
{
//wait for all the display stuff to be created before trying to access it. The constructor function can run before timeline stuff is created, so it's not safe to reference stage or timeline objects here.
if(!stage){
this.addEventListener(Event.ADDED_TO_STAGE, timelineCreated);
}else {
timelineCreated(null);
}
}
private function timelineCreated(e:Event):void {
//now that we're certain the timeline stuff has been created, we can reference timeline objects and stage:
//store the initial z-index of myCircle
myCircleIndex = getChildIndex(myCircle);
//the rest of your code that was in the construction -Main()- before
myCircle.addEventListener(MouseEvent.MOUSE_DOWN, mouseClicking);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseReleased);
}
//no change to any of the following stuff
public function mouseClicking(e:MouseEvent): void
{
myCircle.startDrag();
setChildIndex(myCircle, numChildren-1);
}
public function mouseReleased(e:MouseEvent): void
{
myCircle.stopDrag();
setChildIndex(myCircle, myCircleIndex);
}
}
All you need to do to put the circle behind the square is on release do addChild(myRectangle) or addChildAt(myCircle, 0);
You are overcomplicating things by trying to track a variable in my opinion. Let flash sort it out behind the scenes.
If you want a little more finesse and want to just put the circle directly behind the square (if there were 100 layers and the square is at level 12, but you aren't sure which level the square is at) you could do
addChildAt(myCircle, getChildIndex(myRectangle)-1);
note
setChildIndex(myCircle, numChildren-1);
That's fine to do it that way. The more common way to do this is just
addChild(myCircle);
It does the exact same thing. Many people are confused by this thinking this would add a new myCircle but it just brings it to the front if it's already in the display list, and if it's not in the display list, it adds it to the display list at the top z-order (numChildren-1).
I have UI buttons to toggle sound. OnClick event is linked to this singleton GameObject. when I move to the next scene and come back to the main scene, I find OnClick object becomes missing while object is still there in the hierarchy! so what's the problem ?
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class SoundsManagerController : MonoBehaviour {
static SoundsManagerController Instance = null;
void Awake()
{
// First we check if there are any other instances conflicting
if (Instance != null )
{
// If that is the case, we destroy other instances
Destroy(gameObject);
}
else {
// Here we save our singleton instance
Instance = this;
// Furthermore we make sure that we don't destroy between scenes (this is optional)
DontDestroyOnLoad(gameObject);
}
}
public void toggleSound(){
Instance.GetComponent<AudioSource> ().enabled = !Instance.GetComponent< AudioSource> ().enabled;
}
}
Use a separate canvas for the button and keep them as child of the singleton object.
If you already have a canvas in the scene, make sure the button is set as child of the canvas whenever your are going to a scene.
When these should be fixing your issue, you should consider not using a button with the singleton object. Get the singleton object in Start() in any scene and access sound toggle from the already placed button which is maintaining your UI layout.
Get the singleton object at start that holding the toggle method calling function.
SoundManagerController soundManager;
void Start ()
{
soundManager = GameObject.FindWithTag("audio_manager_tag").GetComponent <SoundManagerController>();
}
Call the below method from toggle button.
public void CallToggleMethod()
{
soundManager.toggleSound ();
}