I don't know how to do - c#

this is my error
Assets\Standard Assets\Characters\ThirdPersonCharacter\Scripts\AICharacterControl.cs(7,31):
error CS0118:'NavMeshAgent' is a namespace but is used like a type
This is my code I can't fix that :(
using System;
using UnityEngine;
namespace UnityStandardAssets.Characters.ThirdPerson.NavMeshAgent
{
[RequireComponent(typeof (NavMeshAgent))]
[RequireComponent(typeof (ThirdPersonCharacter))]
public class AICharacterControl : MonoBehaviour
{
public NavMeshAgent agent { get; private set; }
public ThirdPersonCharacter character { get; private set; }
public Transform target;
private void Start()
{
agent = GetComponentInChildren<NavMeshAgent>();
character = GetComponent<ThirdPersonCharacter>();
agent.updateRotation = false;
agent.updatePosition = true;
}
private void Update()
{
if (target != null)
{
agent.SetDestination(target.position);
character.Move(agent.desiredVelocity, false, false);
}
else
{
character.Move(Vector3.zero, false, false);
}
}
public void SetTarget(Transform target)
{
this.target = target;
}
}
}
thank you

Don't use the names of existing types as namespaces. You have a custom namespace here:
namespace UnityStandardAssets.Characters.ThirdPerson.NavMeshAgent
So anything within that namespace (or in code which references the enclosing namespace) which refers to NavMeshAgent will be referring to the namespace. Not to the type in Unity.
Rename your namespace. For example:
namespace UnityStandardAssets.Characters.ThirdPerson.MyNavMeshAgent
(Or something more contextually meaningful.)
Basically the lesson here is that names matter. The names of your namespaces, types, variables, etc. should be clear and unambiguous to both you and to the compiler.
And, of course, to reference that type directly you'll need a using directive:
using UnityEngine.AI;

Related

Unity ECS | Entities don't render/show up

I'm trying to create a new game with Unity ECS following these tutorials:
https://www.youtube.com/watch?v=H7zAORa3Ux0
https://www.youtube.com/watch?v=IO6_6Y_YUdE
However I'm seem to be stuck already at the very basics.
I have a HexGrid object inside a Subscene with an mono HexGridAuthoringComponent.
This Components holds a reference to a prefab.
I bake the prefab reference with a Baker<> to an Entity.
I try to spawn the Entity with a System.
That works. The Entity shows up in the Hierachy and seems to have the proper components in the inspector.
However I can not see any of the Entities in the game or scene view.
Code:
HexGridProperties (The Data component for the HexGrid Entity)
using Unity.Entities;
using UnityEngine;
namespace HexGrid
{
public struct HexGridProperties : IComponentData
{
public Entity HexCellPrefab;
}
}
HexGridAuthoring (The MonoBehaviour on the HexGrid object + The Baker)
using Unity.Entities;
using UnityEngine;
namespace HexGrid
{
public class HexGridAuthoring : MonoBehaviour
{
public GameObject HexGrid;
}
public class HexGridBaker : Baker<HexGridAuthoring>
{
public override void Bake(HexGridAuthoring authoring)
{
AddComponent(new HexGridProperties
{
HexCellPrefab = GetEntity(authoring.HexGrid)
});
}
}
}
HexGridAspect;
using Unity.Entities;
namespace HexGrid
{
public readonly partial struct HexGridAspect : IAspect
{
public readonly Entity Entity;
private readonly RefRO<HexGridProperties> _hexGridProperties;
public Entity HexCellPrefab => _hexGridProperties.ValueRO.HexCellPrefab;
}
}
HexCellSpawnSystem (The System responsible for spawning the cells of the grid):
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
namespace HexGrid
{
[BurstCompile]
[UpdateInGroup(typeof(InitializationSystemGroup))]
public partial struct HexCellSpawnSystem : ISystem
{
[BurstCompile]
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate<HexGridProperties>();
}
[BurstCompile]
public void OnDestroy(ref SystemState state)
{
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
state.Enabled = false;
var hexGridEntity = SystemAPI.GetSingletonEntity<HexGridProperties>();
var hexGrid = SystemAPI.GetAspectRO<HexGridAspect>(hexGridEntity);
var ecb = new EntityCommandBuffer(Allocator.Temp);
for (int i = 0; i < 100; i++)
{
ecb.Instantiate(hexGrid.HexCellPrefab);
}
ecb.Playback(state.EntityManager);
}
}
}
Full Project: https://github.com/PMSSMP/HexWorld
Editor: 2022.2.3f1
Entities: 1.0.0-pre.15
Entities-Graphics: 1.0.0-pre.15
try reimporting the graphics package, then restart the project and visual studio. I faced the same problem and this fixed mine. Further try recreating the subscene and gameobject as well.

Unity player controller giving CS0246 error

I'm having an error on line 19 Character 16, I am getting a CS0246 error, this code is taken from a public character controller so I'm not sure what's happening. The error also shows up on line 14 character 52 for IPlayerController.
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using TarodevController;
namespace TarodevController
{
/// <summary>
/// Hey!
/// Tarodev here. I built this controller as there was a severe lack of quality & free 2D controllers out there.
/// Right now it only contains movement and jumping, but it should be pretty easy to expand... I may even do it myself
/// </summary>
public class PlayerController : MonoBehaviour, IPlayerController
{
// Public for external hooks
public Vector3 Velocity { get; private set; }
public FrameInput Input { get; private set; }
public bool JumpingThisFrame { get; private set; }
public bool LandingThisFrame { get; private set; } = false;
public Vector3 RawMovement { get; private set; }
public bool Grounded => Cooldown;
private Vector3 _lastPosition;
private float _currentHorizontalSpeed, _currentVerticalSpeed;
}
}
Thank You if you know what's happening, the code is referenced again in the input section, for timing the jump.
private void GatherInput()
{
Input = new FrameInput
{
JumpDown = UnityEngine.Input.GetButtonDown("Jump"),
JumpUp = UnityEngine.Input.GetButtonUp("Jump"),
X = UnityEngine.Input.GetAxisRaw("Horizontal")
};
if (Input.JumpDown)
{
_lastJumpPressed = Time.time;
}
}
Here's the full code if it helps, https://github.com/Matthew-J-Spencer/Ultimate-2D-Controller/blob/main/Scripts/PlayerController.cs
Edit, Here is the error message:
PlayerController.cs(19,16): error CS0246: The type or namespace name 'FrameInput' could not be found (are you missing a using directive or an assembly reference?)
The necessary functions exist in the two other scripts that Tarodev has in the scripts folder of the git repo, I imported both and no errors come up for me.

Unity C# creating observable variables with delegates

What I'm trying to do:
A ScriptableObject class to hold a single variable that can be subscribed to in an observer pattern to receive notifications when the value changes.
My intent is to have things like a UI display update when whatever they display changes, without having to manually trigger an event on every change.
Additionally, I want my class to have three features:
Use try/catch in order to really decouple things and not make all listeners fail just because one did
Have the option to log stuff for debugging
Show the list of currently active observers in the inspector
I thought that's a few lines of code with Delegates, but it turns out nope, that simply doesn't work.
My first naive iteration was this:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
[CreateAssetMenu(fileName = "New Observable Float", menuName = "Observables/Float")]
public class ObservableFloat : ScriptableObject {
public event Action<float> get;
[SerializeField] private float m_Value;
public float Value {
get {
return m_Value;
}
set {
m_Value = value;
get?.Invoke(value);
}
}
}
My second iteration, which works functionally, but doesn't show me the list of observers in the inspector, was this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
[CreateAssetMenu(fileName = "New Observable Float", menuName = "Observables/Float")]
public class ObservableFloat : ScriptableObject {
[SerializeField] List<UnityAction<float>> listeners = new List<UnityAction<float>>();
[SerializeField] private float m_Value;
public float Value {
get {
return m_Value;
}
set {
m_Value = value;
foreach (UnityAction<float> action in listeners) {
action.Invoke(value);
}
}
}
public void AddListener(UnityAction<float> func) => listeners.Add(func);
public void RemoveListener(UnityAction<float> func) => listeners.Remove(func);
}
My third iteration, replacing UnityAction with UnityEvents, appears to work at first glance (the list shows up in the Inspector), but it never updates the list and it's always shown as empty, even though again functionally it works:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using Sirenix.OdinInspector;
[CreateAssetMenu(fileName = "New Observable Float", menuName = "Observables/Float")]
public class ObservableFloat : ScriptableObject {
public UnityEvent<float> listeners = new UnityEvent<float>();
[SerializeField] private float m_Value;
public float Value {
get {
return m_Value;
}
set {
m_Value = value;
listeners?.Invoke(value);
}
}
}
In general I think what you are looking for would be UnityEvent
[SerializeField] private UnityEvent<float> listeners;
public void AddListener(Action<float> action) => listeners.AddListener(action);
public void RemoveListener(Action<float> action) => listeners.RemoveListener(action);
[SerializeField] private float m_Value;
public float Value {
get {
return m_Value;
}
set {
m_Value = value;
listeners?.Invoke(value);
}
}
Unfortunately these will always only show the persistent listeners in the Inspector. There is no simple built-in way to also display runtime callbacks, and if you want to do this I guess there is no way around Reflection and/or a very complex special Inspector implementation.
You could e.g. store something like
using System.Reflection;
using System.Linq;
...
[Serializable]
public class ListenerInfo
{
public Action<float> action;
public string MethodName;
public string TypeName;
}
[SerializeField] private List<string> listenerInfos;
public void AddListener(Action<float> action)
{
listeners.AddListener(action);
var info = action.GetMethodInfo();
listenerInfos.Add(new ListenerInfo { action = action, MethodName = info.Name, TypeName = info.DeclaringType.Name });
}
public void RemoveListener (Action<float> action)
{
listeners.RemoveListener(action);
var info = var info = action.GetMethodInfo();
listenerInfos.RemoveAll(l => l.action == action);
}
Also see e.g. Action delegate. How to get the instance that call the method
I guess that would kinda be the closest you can get without really diving deep into Unity Editor scripting and even more reflection ^^
I've come up with a solution that works, though I'm not perfectly sure about it, so I posted it in CodeReview - https://codereview.stackexchange.com/questions/272241/unity3d-observable-variable
Here's the code (but check the above link for possible fixes/improvements). A huge thanks to #derHugo who pointed me in the right direction:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEditor;
using Sirenix.OdinInspector;
[CreateAssetMenu(fileName = "New Observable Float", menuName = "Observables/Float")]
public class ObservableFloat : ScriptableObject {
[System.Serializable]
public class Listener {
[DisplayAsString, HideInInspector] public int ID;
[DisplayAsString, HideLabel, HorizontalGroup] public string Observer;
[DisplayAsString, HideLabel, HorizontalGroup] public string Method;
[HideInInspector] public UnityAction<float> Callback;
public Listener(UnityAction<float> cb) {
ID = cb.GetHashCode();
Observer = cb.Target.ToString();
Method = cb.Method.ToString();
Callback = cb;
}
}
[Delayed]
[OnValueChanged("NotifyListeners")]
[SerializeField] private float m_Value;
public float Value {
get {
return m_Value;
}
set {
m_Value = value;
NotifyListeners();
}
}
[Tooltip("Log Invoke() calls")]
[SerializeField] bool Trace;
[Tooltip("Use try/catch around Invoke() calls so events continue to other listeners even if one fails")]
[SerializeField] bool CatchExceptions;
[ListDrawerSettings(DraggableItems = false, Expanded = true, ShowIndexLabels = false, ShowPaging = false, ShowItemCount = true)]
[SerializeField] List<Listener> listeners = new List<Listener>();
void Awake() {
// clear out whenever we start - just in case some observer doesn't properly remove himself
// maybe later I'll also add persistent listeners, but for now I don't see the use case
listeners = new List<Listener>();
}
void NotifyListeners() {
foreach (Listener listener in listeners) {
if (Trace) {
Debug.Log("invoking "+listener.Observer+" / "+listener.Method+ " / value = "+m_Value);
}
if (CatchExceptions) {
try {
listener.Callback.Invoke(m_Value);
} catch (System.Exception exception) {
Debug.LogException(exception, this);
}
} else {
listener.Callback.Invoke(m_Value);
}
}
}
public void AddListener(UnityAction<float> func) { listeners.Add(new Listener(func)); }
public void RemoveListener(UnityAction<float> func) { listeners.RemoveAll(l => l.ID == func.GetHashCode()); }
}
This works and gives me the features I wanted, not sure if it's a great solution, so I'll leave the question open for better answers.

'object' doesn't contain a definition for 'keyCount'

I'm pretty new to coding and this script is giving me an error. It's suppose to pick up a key for a door.
It says it's error CS1061 'object' does not contain a definition for 'keyCount' and no accessible extension method 'keyCount' accepting a 1st argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
I tried double checking the script and matching it up to a tutorial I was watching. still no affect. I don't know how to make a definition (Idk where to look to find that).
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class keyitems
{
public static int keyCount;
}
public class keyitem : MonoBehaviour
{
public object GameVariables { get; private set; }
void OnTriggerEnter(Collider collider)
{
{
if (collider.gameObject.name == "Player")
{
GameVariables.keyCount += 2;
Destroy(gameObject);
}
}
}
}
I would like to pick up a key to open a door. any help on this would be amazing.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class keyitems
{
public static int keyCount;
}
public class keyitem : MonoBehaviour
{
public object GameVariables { get; private set; }
void OnTriggerEnter(Collider collider)
{
{
if (collider.gameObject.name == "Player")
{
keyitems.keyCount += 2;
Destroy(gameObject);
}
}
}
}
keyCount variable is keyitems's variable. So, you can get it like this :
keyitems.keyCount
And, I recommend you to use camel case when typing class name.
For example : KeyItems ( not keyitems )

Sending a Boolean as a field to another script

I saw this question asked some times but no one correlates to mine. I see people using the GetComponent() function but this one should work too.
First I receive a Bool value from a toggle button and assign it as a field of the object 'hydro':
hydroControl.cs
using UnityEngine;
using System.Collections;
using Assets.Code.PowerPlants;
public class hydroProwerControlPanel : MonoBehaviour {
private HydroElectric hydro;
public bool t1;
void Start ()
{
t1 = true;
}
public hydroProwerControlPanel (){
hydro = new HydroElectric();
}
public void turbine1State (bool t1) {
hydro.t1Bool = t1;
}
The I have the object where this bool change should be recognized and sent as an output, but it doesn't:
using System;
using UnityEngine;
namespace Assets.Code.PowerPlants
{
public class HydroElectric
{
public bool t1Bool;
float turbina1;
public float prod;
public HydroElectric ()
{
t1Bool = true;
prod = 0f;
}
public float ControlPanel ()
{
turbina1 = t1Bool ? 1.5F : 0;
prod = turbina1 ;
Debug.Log (prod);
return prod;
}
}
}
As requested, this is where the function ControlPanel() is called:
using System;
using UnityEngine;
using UnityEngine.UI;
using Assets.Code.PowerPlants;
namespace Assets.Code.Interfaces
{
public class PlayLevel1 : MonoBehaviour
{
private HydroElectric hydro;
public Text producao;
public PlayLevel1 ()
{
hydro = new HydroElectric();
}
public void OnGUI()
{
producao.text = hydro.ControlPanel().ToString();
}
}
}
Do you have any idea why does this Bool does not get updated? Any help appreciated.
PlayLevel1's Hyrdo and hydroProwerControlPanel's hydro object are two different instances. Change in one instance will not reflect the change in second instance both are independent instances .
The thing you want to achieve is only possible if you make HydroElectric static class with static members.
Hope it will help.

Categories

Resources