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.
Related
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;
I am new with unity and C#, I have question about how I save current scrollrect position.
Example : I am scrolling the view , and move to another scene and then back to previous scene but the scroll shows the previous position before I moved the scene, not resetting the scroll to default.
Unfortunately, what you want to make is not available ready-made, you have to make it yourself
first use Recyclable-Scroll-Rect
When scrolling to the bottom of the scroll, you have to save the id you sent to DemoCall via PlayerPrefs, then when you go to another scene and back again to the selected scene, call the scroll info from the point it left off, which is the id you saved
EDIT
After adding the Recyclable-Scroll-Rect, you can use this code
using System.Collections.Generic;
using UnityEngine;
using PolyAndCode.UI;
using System.Collections;
public struct ContactTsnif
{
public string id;
}
public class Objx
{
public string id;
}
public class RecyclTsnif : MonoBehaviour, IRecyclableScrollRectDataSource
{
[SerializeField]
RecyclableScrollRect _recycHat;
public GameObject RecyScrHat;
[SerializeField]
public int _dataLenHat;
public int beginning;
private List<ContactTsnif> _contactList = new List<ContactTsnif>();
public List<string> id = new List<string>();
void Start()
{
beginning = PlayerPrefebs.GetInt("Start", 5)// start with 5
GetHat();
}
public void GetHat()
{
_dataLenHat = 0;
_recycHat.DataSource = this;
InitDataHat();
RecyScrHat.GetComponent<RecyclableScrollRect>().Initialize();
}
public void InitDataHat()
{
if (_contactList != null) _contactList.Clear();
for (int i = beginning; i < _dataLenHat;)
{
ContactTsnif obj = new ContactTsnif();
obj.id = id[i];
i++;
_contactList.Add(obj);
}
}
#region DATA-SOURCE
public int GetItemCount()
{
return _contactList.Count;
}
public void SetCell(ICell cell, int index)
{
var item1 = cell as DemoTsnif;
item1.ConfigureCellSor(_contactList[index], index);
}
#endregion
}
Demo
using UnityEngine;
using System;
using System.Collections;
public class DemoTsnif : MonoBehaviour, ICell
{
private ContactTsnif _ContactInfo;
private int _cellIndex;
public int id;
public void GetData()
{
}
public void ConfigureCellSor(ContactTsnif contactInfo,int cellIndex)
{
_cellIndex = cellIndex;
_ContactInfo = contactInfo;
id = contactInfo.id;
GetData();
}
}
Do you tried read / write normalizedPosition?
You basically need to do two things:
You need to attach this script to the GameObject which contains the ScrollRect in order to persist the position:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems; // Required when using event data
using UnityEngine.UI;
public class DragNotify : MonoBehaviour, IEndDragHandler // required interface when using the OnEndDrag method.
{
//Do this when the user stops dragging this UI Element.
public void OnEndDrag(PointerEventData data)
{
PlayerPrefs.SetFloat("scrollX", this.GetComponent<ScrollRect>().normalizedPosition.x);
}
}
You also need to apply the normalizedPosition once you initialized the ScrollRect and after you applied the desired content:
this.transform.Find("Scroll View").GetComponent<ScrollRect>().normalizedPosition = new Vector2(PlayerPrefs.GetFloat("scrollX"), 0F);
I have three scripts inside GameObjects strucured as following:
GameObjectA
└ Script1
GameObjectB
└ Script2
└ Script3
Script3 has a Dictionary I need to recall in Script2:
public void SomeMethod()
{
Dictionary<string, int> someDictionary;
someDictionary = gameObject.GetComponent<Script3>().myDictionary;
//other stuff
}
If I call the method in Script2 in its Start method, it gets called and normally, and the Dictionary is read without problems.
However, during code execution, I'll sometimes need to call Script2 from Script1:
Public GameObject GameObjectB;
GameObjectB.GetComponent<Script2>().SomeMethod();
and, if I do so, when stepping through code during execution I realize the Dictionary SomeDictionary is empty.
Is this normal? I can give more information or the real snippets if needed, I find this behavior weird and I don't know if it acts regularly.
Edit: real codes below.
Script1, PauseMenu:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PauseMenu : MonoBehaviour
{
public GameObject tracksMenuContent;
public void TracksList()
{
tracksMenuContent.GetComponent<PopulateGrid>().Populate();
}
}
Script2, PopulateGrid:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PopulateGrid : MonoBehaviour
{
[SerializeField] private TileDescr _prefab;
public static PopulateGrid instance;
private void Awake()
{
Populate();
}
public void Populate()
{
Dictionary<string, TileSupply> tilesList;
tilesList = gameObject.GetComponent<TileDB>().tiles30;
TileDescr newObj; // Create GameObject instance
foreach (KeyValuePair<string, TileSupply> tile in tilesList)
{
Sprite tileSprite = Resources.Load<Sprite>("Tiles/tile" + tile.Key);
string tileText = "[" + tile.Key + "] " + tile.Value.available + "/" + tile.Value.total;
newObj = Instantiate(_prefab, transform);
newObj.Initialize(tileSprite, tileText);
}
}
}
Script3, TileDB:
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TileSupply
{
public int available;
public int total;
}
public class TileDB : MonoBehaviour
{
public Dictionary<string, TileSupply> tiles30 = new Dictionary<string, TileSupply>();
public void Awake()
{
tiles30.Add("1", new TileSupply() { available = 1, total = 1 });
//many more elements, all pretty similar
}
}
a possible solution is to use static:
public class TileDB : MonoBehaviour
{
public static Dictionary<string, TileSupply> tiles30 = new Dictionary<string, TileSupply>();
public void Awake()
{
tiles30.Add("1", new TileSupply() { available = 1, total = 1 });
}
}
after to use the tiles30 in other script, just call the dictionary like that
TileDB.tiles30
I had been searching so much to solve my problem but I found nothing.
So, what is my problem?
I have a class that extends from UnityEvent and it has 2 virtual methods and it has public identifier in another file that should call those methods. But when I put my script in inspector nothing happens (except root virtual methods).
The class:
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
namespace Namespace {
[System.Serializable]
public class SomeClass : UnityEvent {
public virtual void OnSomething(GameObject objectSender, GameObject objectAction) {
}
public virtual void OnSomethingElse(GameObject objectSender, GameObject objectAction) {
}
}
}
I overrided those methods in a file and but in variable "script" shown below but they are not overrided.
And using of SomeClass:
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
namespace Namespace {
public class ActionListener : MonoBehaviour {
public SomeClass script;
// When I lose last hope
// private void Start() {
// script.Invoke();
//}
public void OnHover(GameObject sender, GameObject action) {
script.OnHoverListener(sender, action);
}
public void OnClick(GameObject sender, GameObject action) {
script.OnClickListener(sender, action);
}
}
}
I have solved this problem using MonoBehaviour instead UnityEvent.
And not it looks like this
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
namespace Namespace {
public class SomeClass : MonoBehaviour {
public virtual void OnSomething(GameObject objectSender, GameObject objectAction) {
}
public virtual void OnSomethingElse(GameObject objectSender, GameObject objectAction) {
}
}
}
And in use
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
namespace Namespace {
public class ActionListener : MonoBehaviour {
public SomeClass script;
public void OnHover(GameObject sender, GameObject action) {
script.OnSomething(sender, action);
}
public void OnClick(GameObject sender, GameObject action) {
script.OnSomethingElse(sender, action);
}
}
}
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.