`UnityEngine.Component.guiTexture' is obsolete: [duplicate] - unity3d

The code to play animation on trigger button does not seem to work. I saw a video on Youtube and with a simple animation.Play(); it worked on that video but yet, I couldn't get it to work on my computer. What did I do wrong or did unity change it? please help I cant find solution on the net. All the "solution not working either".
This is the error I got:
Type UnityEngine.Component does not contain a definition for play
and no extension method Play of type UnityEngine.component could
be found
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class animationtrigger : MonoBehaviour {
void Start()
{
}
int speed = 10;
// Update is called once per frame
void Update () {
if (Input.GetKeyDown("N"))
{
animation.Play("Cube|moving side");
//transform.Translate(1 * Vector3.forward * Time.deltaTime * speed);
//Animator anim = GetComponent<Animator>();
//if (null != anim)
// {
// anim.Play("Cube|moving side");
// }
}
}
}

what did i do wrong or did unity change it?
Unity changed. I've seen similar questions for the past few weeks. Although I don't think they are duplicates but it would make sense to answer all these here for future questions.
The animation variable is defined under Component as a public variable which MonoBehaviour inherits from. Your code then inherits from MonoBehaviour and you have access to animation.
These are the complete list of variables from the Component class that are deprecated:
public Component animation { get; }
public Component audio { get; }
public Component camera { get; }
public Component collider { get; }
public Component collider2D { get; }
public Component constantForce { get; }
public Component guiElement { get; }
public Component guiText { get; }
public Component guiTexture { get; }
public Component hingeJoint { get; }
public Component light { get; }
public Component networkView { get; }
public Component particleEmitter { get;
public Component particleSystem { get; }
public Component renderer { get; }
public Component rigidbody { get; }
public Component rigidbody2D { get; }
New way to access component that attached to the-same script:
Use GetComponent<ComponentName>(). Capitalize the first letter of that variable to make it its component class. One exception is audio which becomes
AudioSource instead of Audio.
1.animation.Play("Cube|moving side"); becomes GetComponent<Animation>().Play("Cube|moving side");
2.rigidbody2D.velocity becomes GetComponent<Rigidbody2D>().velocity
3.rigidbody.velocity becomes GetComponent<Rigidbody>().velocity
4.renderer.material becomes GetComponent<Renderer>().material
5.particleSystem.Play() becomes GetComponent<ParticleSystem>().Play()
6.collider2D.bounds becomes GetComponent<Collider2D>().bounds
7.collider.bounds becomes GetComponent<Collider>().bounds
8.audio.Play("shoot"); becomes GetComponent<AudioSource>().Play("shoot");
9.camera.depth becomes GetComponent<Camera>().depth
I don't have to put all of them because the example below should guide anyone do this. These are the most asked and asked components on SO.
Cache Component:
You can cache component so that you don't have be GetComponent everytime.
Animation myAnimation;
void Start()
{
//Cache animation component
myAnimation = GetComponent<Animation>();
}
void Update()
{
if(somethingHappens)
{
//No GetComponent call required again
myAnimation.Play("Cube|moving side");
}
}

If you're using an animator and you want to play a specific state, then you can do:
animator.Play("stateName");
I see that in the commented code below. That should be working. If nothing is happening then make sure that the "Cube|moving side" is a STATE name and not the ANIMATION name. Also make sure that the state actually contains an animation, and that the animation actually has frame data.
(Below, I have 2 states (Move and Idle). The state name is "Move" while the animation name is "test".)
If I wanted to switch to the move state, I would call animator.Play("Move").
Also I wouldn't recommend explicitally playing states. If you can manage it's generally better to make a state tree and trigger animations using parameters. You see in the image above how I have two states and transitions between them. You can assign parameters that can make my animator switch from one to another.
Here I use the "Example Anim Trigger" to make the animator switch from the Idle to Move state. I could do this in code with:
animator.SetTrigger("ExampleAnimTrigger");
This is the more modern way of using Unity animations, so I'd highly recommend picking this up.
Here's the documentation!

Related

Giving Scriptable Objects a reference to a custom abstract class

I'm working on a 2d Topdown game for my senior project, and I'm coming across a bit of a design issue. Currently, the plan is for the player to be able to hold 1 weapon for each of three classes (melee, ranged, magic). They can pick these items up on the map, and it will be added to their inventory. These items carry 2 attacks each, and whichever weapon is active in their inventory gives the player their two attacks they can use.
Here's the base class for the Item ScriptableObject:
public class BaseItemSO : ScriptableObject
{
[SerializeField] private string itemName;
[SerializeField] private string description;
[SerializeField] GameObject model;
[SerializeField] Sprite inventoryIcon;
public string getName() { return itemName; }
public string getDescription() { return description; }
public GameObject getModel() { return model; }
public Sprite getIcon() { return inventoryIcon; }
}
The GameModel holds the item's overworld sprite, its collider, the usual stuff.
Then we have the WeaponItemSO. This inherits from Item, and it meant for the weapons that the player can pick up. It has a weapon class (same melee, ranged, magic) and I'm attempting to give it two references to some sort of Attack script.
{
[SerializeField] private WeaponClass weaponClass;
[SerializeField] private BaseAttackController attack1;
[SerializeField] private BaseAttackController attack2;
public enum WeaponClass
{
Melee,
Ranged,
Magic
}
}
The problem I'm running into is that each attack has a different script. I haven't implemented baseAttackController, but the plan was for each to have an OnAttack() and dealDamage() and whatever else is necessary, and these attacks could be read from the WeaponSO that the player holds. Unfortunately, Unity can't serialize these abstract classes or interfaces. What might be a pattern I should go about here?
I haven't implemented further yet, but my ideas have included simply putting those attack controllers on the GameModel that is referenced. Then the player could read that, but it certainly doesn't feel like the right approach, the attack class should be able to exist with or without a player or gameobject.

Sorting by property of foreign key object

I'm making a third party app for a game.
In my domain I have the class 'player'. Players can attack/defend attacks of other players and while doing so they earn attacking/defending points. The API of the game is pretty awful (Online txt files in csv format) so there's little manipulation I can do other than bulk insert the files into my database and work from there.
Doing so I have a player table and a Points_Att table. In my EF configuration Player owns one Points_Att and Points_Att has one property: points. And each player has a 'Player_Att' object.
I'm trying to get the top X attackers from the database. But I can't sort on Player_Att.points, I tried the following code:
return _players.Where("conditions").OrderBy(p => p.Points_Att.Points).Take(X).ToList();
This gives me an array of the first X players in my database, it doesn't sort. I tried changing the Player_Att object to an int which would be easier to work with but my limited knowledge seems to stop me from doing so...
So basically I need to sort on player.Points_Att.Points or I need an int object rather than a Player_Att object.
If anything isn't clear please feel free to ask, I browsed my problem for a couple of hours now and i'm not getting any further.
Thanks in advance.
EDIT:
Models:
public class Player
{
public Player_Att PointsAttacking { get; private set; }
}
public class Player_Att
{
public int Points { get; private set; }
}
Mapping:
internal class PlayerConfiguration : IEntityTypeConfiguration<Player>
{
public void Configure(EntityTypeBuilder<Player> builder)
{
builder.OwnsOne(p => p.PointsAttacking).OnDelete(DeleteBehavior.Cascade);
}
public class Player_AttConfiguration : IEntityTypeConfiguration<Player_Att>
{
public void Configure(EntityTypeBuilder<Player_Att> builder)
{
builder.ToTable("Player_Att");
}
}

Setting Properties in Unity Editor

As much as it makes sense I'm trying to use interfaces when working with scripts, something like this:
public interface IConsumable
{
Sprite Icon { get; set; }
}
However when using this approach, any classes implementing the interface do not show these properties in the inspector and I end up with something like this:
public class TestConsumable : MonoBehaviour, IConsumable
{
public Sprite Icon { get { return IconSprite; } set { IconSprite = value; } }
// Hack just to show up in Editor
public Sprite IconSprite;
}
This doesn't really make sense to me and I was hoping there was a better solution.
Side-note, I'm not using getters / setters exclusively for Interfaces but also for some validation etc.
Thanks!
By default properties with get/set will not show up in the editor. You need to mark them with the "[SerializeField]" attribute in order to use them in the editor. The reason is that unity will only display types that it can save.
public class TestConsumable : MonoBehaviour, IConsumable
{
[SerializeField]
private Sprite icon;
public Sprite Icon { get { return icon; } set { icon = value; } }
}

How to handle updating an animation from an IDrawable?

I have two interfaces, IDrawable and IUpdateable. Some concrete drawables are updateable, but not all. A sprite with animations, for example, implements both IDrawable and IUpdateable but a static image just implements IDrawable.
The problem is obvious... how could I possibly update animations with just an IDrawable reference? If I pass a Sprite to a Button to use as it's graphic representation, the Button just remains static because it can't advance it's sprite animations.
Ideas?
A solution is to define a new abstraction:
public interface IXXXObject {
IDrawable Drawable { get; } // return null if not support IDrawable
IUpdatable Updatable { get; } // return null if not support IUpdatable
}
All your objects should implement this interface.
Now you should pass objects as IXXXObject and you can call a feature if it is supporting.

MVVM - Deciding which ViewModel is responsible for what

I have a simple app that consists of:
Model
Items
Filter criteria applied to that list of items
Views
WelcomePage
MainItemsPage
FilterEditPage
I am using MVVM Light and Windows Phone 7
I currently have 3 ViewModels, one for each View. In the past I have had a single ViewModel which made the comunication which I am about to ask about very easy. However I wanted to go with the 3 seperate VMs as that seems to be the correct way.
The WelcomePage is able to set one of the Filter criteria before navigating to the MainItemsPage. The MainItemsPage is bound to an Items property that is exposed by its ViewModel. That ViewModel needs to have filtered that list depending on the current filter criteria. The FilterEditPage allows the user to edit the full criteria set of 4 variables. When the criteria is changed the Items collection used in the ViewModel for MainItemsPage needs to be refiltered.
The question is how I flow the Filter changes through the app. I know that MVVM has the concept of Messaging and the MVVM Light toolkit provides the Messenger class. However what I am struggling with is where does the responsibility lie for sending those messages?
Do the 3 VMs go to the Model whenever they need to work with the current Filter set?
Do all Filter updates go through the FilterEditViewModel and that in turn broadcasts a filter change message?
Do I go back to a single VM for all the Views?
I cannot see 1. working because something will need to trigger the VMs to go back to the Model
I know I can get 3. working right now with no problem. Is it that wrong?
TIA
Pat Long
I would put the shared current filter in the Model not the view model. You've got lots viewModels potentially on different pages or on the same page (consider a breadcrumb showing current selection and something else that needs to show a filter has been applied).
How about a singleton model for the Filter that view models can subscribe to?
Three VMs is the right way in your scenario. I suggest you to build a Parent/Child relation between you VMs. Since the the MainVM holds the ItemList, this is the place, where FilterChanges are applied. The FilterEditVM only receives the filter changes and than calls the MainVM, that it has to re-apply the filters.
The structure would be something like this:
public class WelcomePageVM
{
public WelcomePageVM()
{
this.FilterEditPageVM = new FilterEditPageVM(this);
this.MainItemsVM = new MainItemsVM(this);
}
public FilterEditPageVM FilterEditPageVM { get; private set; }
public MainItemsVM MainItemsVM { get; private set; }
public void SetInitialFilter1(object filter)
{
// the initial filter
this.FilterEditPageVM.Filter1Value = filter;
this.MainItemsVM.ApplyFilters();
}
}
public class FilterEditPageVM : ChildViewModelBase<WelcomePageVM>
{
public FilterEditPageVM(WelcomePageVM parent)
: base(parent) { }
public object Filter1Value { get; set; }
public object Filter2Value { get; set; }
public object Filter3Value { get; set; }
public object Filter4Value { get; set; }
public void FinishFilterChange()
{
this.Parent.MainItemsVM.ApplyFilters();
}
}
public class MainItemsVM : ChildViewModelBase<WelcomePageVM>
{
public MainItemsVM(WelcomePageVM parent)
: base(parent) { }
public List<object> ItemList { get; set; }
public void ApplyFilters()
{
// filter apply logic
}
}
public abstract class ChildViewModelBase<T>
{
T _parent;
public ChildViewModelBase(T parent)
{
this._parent = parent;
}
public T Parent { get { return _parent; } }
}
Here you can access all viewmodels, which is okay because you stay in the "controller" level.