Unity error cs0104

The problem with UnityEngine.Random By Oliver Booth Post date When it comes to game dev, random number generation is a subject that comes up a lot. With the advent of Minecraft, No Man’s Sky, and other games with procedurally-generated environments, unique variation in your game is an attractive feature which increases replayability and enhances […]

Содержание

  1. The problem with UnityEngine.Random
  2. So where does it fall apart?
  3. The Solution, or: How I Learned to Stop Using Unity’s RNG and Love .NET
  4. Substituting everything in UnityEngine.Random
  5. Error cs0104 random is an ambiguous reference between unityengine random and system random
  6. Почему не работает рандом?
  7. Почему не работает рандом?
  8. Re: Почему не работает рандом?
  9. Re: Почему не работает рандом?
  10. Re: Почему не работает рандом?
  11. Re: Почему не работает рандом?
  12. Re: Почему не работает рандом?
  13. Re: Почему не работает рандом?
  14. Re: Почему не работает рандом?
  15. Re: Почему не работает рандом?
  16. Re: Почему не работает рандом?
  17. Re: Почему не работает рандом?
  18. Re: Почему не работает рандом?
  19. Re: Почему не работает рандом?
  20. Re: Почему не работает рандом?
  21. Re: Почему не работает рандом?
  22. Кто сейчас на конференции

The problem with UnityEngine.Random

By Oliver Booth
Post date

When it comes to game dev, random number generation is a subject that comes up a lot. With the advent of Minecraft, No Man’s Sky, and other games with procedurally-generated environments, unique variation in your game is an attractive feature which increases replayability and enhances player experiences.

Unity provides a random number generator (RNG), and you may have already interacted with its API in the form of Random.Range . There is, however, one major flaw with its implementation: it’s a singleton. Why is that a problem, you ask?

Consider this example. Imagine you want to generate objects at random positions in your world. You might do something like this:

We have a coroutine GenerateRandomSpheres which loops 100 times, calling Random.Range to give us random X and Y coordinates between -5 and 5. This would spawn in the sphere prefab 100 times at random locations:

Running it again would yield a slightly different distribution of objects:

This is fine in many cases. However, games such as Minecraft allow the player to specify a “seed”. A seed lets you initialise an RNG so that it produces the same sequence every time, and this is why are you able to share “seeds” with your friends so they can explore the same random world as you. This is interesting, because it means these RNGs are not pure “random”, they are what is known as pseudorandom. They are 100% deterministic based on their initial condition: the seed. UnityEngine.Random allows you specify a seed with the InitState method, so let’s alter the coroutine so that it calls this method with some made up seed like 1234567890 .

Playing the scene again, we see this:

Stop the scene, and play it again. What do we see?

Would you look at that? It’s the exact same distribution from the last time. This is the deterministic behaviour of the pseudorandomness showing its true colours. We could run this once, twice, or a hundred times – but it doesn’t matter. The random sequence is purely determined by its initial state. Change the seed? You change the sequence.

So where does it fall apart?

We have our coroutine to generate a collection of random spheres. Now suppose you wish to introduce random cubes too.

We’ll create a second coroutine called GenerateRandomCubes , but this time we will have it use a different seed like 987654321 (truly revolutionary, right?). It will initialise its own state, while letting the original GenerateRandomSpheres coroutine initialise with its state.

We will add the code to do this but we won’t actually call Instantiate , because otherwise the scene will be a mess of cubes and spheres and it will be difficult to keep track. The important thing is we are still calling Random.Range , the positions of the potential cubes are still being calculated.

If we play the scene, we see this:

Can you spot the problem? It might take a second.

Adding in cube generation broke our expected sequence! Comment out the call StartCoroutine(GenerateRandomCubes()); and you will see, it reverts back to the first pattern we expected. How could this be? Didn’t our coroutines initialise their own random state? They are working with different seeds, right?

As I mentioned earlier, Unity’s RNG is completely static. It is a singleton. In the name of simplicity, Unity has sacrificed something critically important, which is encapsulated state; we only have one Random to work with throughout the entire lifetime of our game. This means adding any new random sequences to our code breaks existing ones.

So how can we work around it?

The Solution, or: How I Learned to Stop Using Unity’s RNG and Love .NET

.NET has had its own implementation of an RNG ever since it was first released. System.Random gives us exactly what we need: encapsulated state.

If you’ve ever had to import both the System namespace and the UnityEngine namespace and been hit with the following error…

… you likely resolved it by either fully qualifying as UnityEngine.Random or by adding a using alias as using Random = UnityEngine.Random; – well now it’s time to do a 180. From now on, you should use System.Random whenever possible.

System.Random works on an instance-basis. The constructor accepts a 32-bit integer as its seed, so let’s go back to our original code where we simply only generate spheres, and change our call to InitState to instead an instantiation of System.Random . Don’t forget to add the using alias so that the compiler knows which type you mean:

Of course, this won’t compile. Random.Range is now undefined because the Random it’s referencing is now .NET, which does not have a static Range method. Instead, we’ll ultimately need to call NextDouble on the instance we just created. There are two problems though: This method returns a double, and it also only returns a value from 0 – 1. What we need is for it to return a float between any two values we want so that we can simulate the behaviour of UnityEngine.Random.Range .

To accomplish this, we can write a quick extension method. Create a new class in a separate file called RandomExtensions , and feel free to copy/paste this code into it:

If you haven’t worked with extension methods before, this syntax might seem a little strange. The keyword this on the parameter is rather unique but it lets us do something very useful, which is access it on an instance of that parameter type. With this we can replace our call to Random.Range with a call to the NextSingle extension method on the random object.

This method also serves as a replacement for Random.value . If we simply pass no arguments and call it as random.NextSingle() , they will use their default values giving us a random float between 0 and 1.

If we play the scene, we’ll see a new random distribution of objects:

You might be wondering why the distribution of objects is different from before, even though we are using the same seed. This is because Unity’s Random doesn’t wrap the .NET Random , it instead calls native code and generates it that way. But this is irrelevant, what matters is consistency. As long as we always use the same mechanism for RNG from the get-go, it will work out. Play the scene again, and you will see the same distribution of objects!

Now, let’s bring back our GenerateRandomCubes coroutine. In this method, we will create a separate Random instance, and use the second seed from last time 987654321 . Again, we will omit the call to Instantiate purely to keep the scene clean, but we will still calculate random positions for where the cubes would go.

Play the scene, and drumroll please…

It worked! The two coroutines declare their own independent instances of System.Random , with their own seeds, which means each instance will generate its own independent sequence of random numbers. Perfect 👌

Substituting everything in UnityEngine.Random

Unity’s RNG does offer some very useful members related to game dev such as insideUnitCircle , onUnitSphere , and the like. We can replicate these using the .NET RNG, by expanding on our RandomExtensions class.

The first thing we will need is a method that, strangely, does not actually replace anything that Unity’s RNG has to offer. There is no onUnitCircle that this method is mimicking. However, it will become invaluable for you I’m sure. NextOnUnitCircle will return a random point which lies on the radius of the unit circle. It is essentially the Vector2 equivalent of onUnitSphere .

We need to generate a random angle (a degree value between 0-360, and convert it to radians), which will serve as the direction that our vector is pointing, and then perform some trigonometry to have a point which lies on the unit circle.

If you are curious about how this method works, then here is a handy illustration which might make it more apparent:

Now we can get to copying over the Unity values. We’ll start with onUnitSphere , so let us define an extension method called NextOnUnitSphere which achieves the same effect.

The math for this is largely similar to the 2D version ( NextOnUnitCircle ), though admittedly a little more involved. Trigonometry is our best friend here:

Now, insideUnitSphere . This one is extremely simple to recreate now that we have NextOnUnitSphere . Since that will return a Vector3 whose magnitude is 1, all we have to do is scale that result by a random float between 0 – 1, to get position inside that sphere!

insideUnitCircle can do almost the same thing. We’ll call the new NextOnUnitCircle we wrote, before scaling it by a random float.

We can substitute UnityEngine.Random.rotation for a method which generates 3 random values between 0 – 360, and calling Quaternion.Euler to wrap it as a quaternion.

UnityEngine.Random.rotationUniform involves Math™, and I’m not going to go into detail about how this method works, primarily because I’m not entirely sure myself (Quaternions – not even once). However we can replicate its functionality like so:

The final method we need to replace is ColorHSV . This one is actually easy to replace since the source for this is method is publicly available. All we have to do is port it to a set of extension methods which perform the same logic:

If you’d like to download the full source code for this RandomExtensions class, you can do so here!

Источник

Error cs0104 random is an ambiguous reference between unityengine random and system random

Текущее время: 15 янв 2023, 14:08

  • Список форумовUnity3DОбщие вопросы
  • Изменить размер шрифта
  • Для печати

Почему не работает рандом?

Почему не работает рандом?

ZhuDen 29 сен 2013, 21:19

хочу сделать рандом Random.Range(2f, 5f); но мне выдаёт две ошибки:
1) Assets/Controller.cs(64,62): error CS0104: `Random’ is an ambiguous reference between `UnityEngine.Random’ and `System.Random’
2) Assets/Controller.cs(64,62): error CS0103: The name `Random’ does not exist in the current context

Никак не пойму что не так.
E11.transform.position = new Vector3(Random.Range(2f, 5f), 3f, 5f);

Re: Почему не работает рандом?

ShyRec 29 сен 2013, 21:24

Re: Почему не работает рандом?

ZhuDen 29 сен 2013, 21:26

Re: Почему не работает рандом?

ShyRec 29 сен 2013, 21:30

using System.Random ;
//или UnityEngine.Random

//и инициализируем, тобеж создаём объект класса
Random rnd = new Random ( ) ;
//и юзаем
E11. transform . position = new Vector3 ( rnd. Range ( 2f, 5f ) , 3f, 5f ) ;

если где не прав, извиняйте. сам-то нуб нубом

Re: Почему не работает рандом?

ZhuDen 29 сен 2013, 21:32

using System.Random ;
//или UnityEngine.Random

//и инициализируем, тобеж создаём объект класса
Random rnd = new Random ( ) ;
//и юзаем
E11. transform . position = new Vector3 ( rnd. Range ( 2f, 5f ) , 3f, 5f ) ;

если где не прав, извиняйте. сам-то нуб нубом

using System.Random;
//или UnityEngine.Random
Никакое из них не работает, по прежнему ошибки, что делать?

Re: Почему не работает рандом?

ShyRec 29 сен 2013, 21:35

using System.Random ;
//или UnityEngine.Random

//и инициализируем, тобеж создаём объект класса
Random rnd = new Random ( ) ;
//и юзаем
E11. transform . position = new Vector3 ( rnd. Range ( 2f, 5f ) , 3f, 5f ) ;

если где не прав, извиняйте. сам-то нуб нубом

using System.Random;
//или UnityEngine.Random
Никакое из них не работает, по прежнему ошибки, что делать?

Попробуй вместо этого сделать так

Re: Почему не работает рандом?

ZhuDen 29 сен 2013, 21:40

using System.Random ;
//или UnityEngine.Random

//и инициализируем, тобеж создаём объект класса
Random rnd = new Random ( ) ;
//и юзаем
E11. transform . position = new Vector3 ( rnd. Range ( 2f, 5f ) , 3f, 5f ) ;

если где не прав, извиняйте. сам-то нуб нубом

using System.Random;
//или UnityEngine.Random
Никакое из них не работает, по прежнему ошибки, что делать?

Попробуй вместо этого сделать так

System.Random rnd = new System.Random(); // Эта строка работает
//и юзаем
E11.transform.position = new Vector3(rnd.Range(2f, 5f), 3f, 5f); // А в вот этой ошибка:
Assets/Controller.cs(65,66): error CS1061: Type `System.Random’ does not contain a definition for `Range’ and no extension method `Range’ of type `System.Random’ could be found (are you missing a using directive or an assembly reference?)

Re: Почему не работает рандом?

ShyRec 29 сен 2013, 21:42

Re: Почему не работает рандом?

ZhuDen 29 сен 2013, 21:46

Re: Почему не работает рандом?

ShyRec 29 сен 2013, 21:49

Я уже даже не знаю. Честно говоря не использовал юнитековский рандом.

using UnityEngine ;
using System.Collections ;
using UnityEngine.Random ;

E11. transform . position = new Vector3 ( Random. Range ( 2f, 5f ) , 3f, 5f ) ;

Всё, больше никаких догадок.

Re: Почему не работает рандом?

ZhuDen 29 сен 2013, 21:51

ShyRec писал(а): Я уже даже не знаю. Честно говоря не использовал юнитековский рандом.

using UnityEngine ;
using System.Collections ;
using UnityEngine.Random ;

E11. transform . position = new Vector3 ( Random. Range ( 2f, 5f ) , 3f, 5f ) ;

Всё, больше никаких догадок.

Re: Почему не работает рандом?

Avatarchik 29 сен 2013, 22:08

Re: Почему не работает рандом?

AndreyMust19 29 сен 2013, 22:46

Re: Почему не работает рандом?

mp3 29 сен 2013, 22:47

Re: Почему не работает рандом?

renegate-All 26 май 2020, 15:36

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 16

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB

Источник

0 / 0 / 0

Регистрация: 23.08.2020

Сообщений: 1

1

23.08.2020, 12:31. Показов 4689. Ответов 4


AssetsgameScenegamePlayer.cs(35,76): error CS0104: ‘Random’ is an ambiguous reference between ‘UnityEngine.Random’ and ‘System.Random’
Пробывал подключать библиотеку UnityEngine.Random и System.Random. Но вылазит другая ошибка error CS0138: A ‘using namespace’ directive can only be applied to namespaces; ‘Random’ is a type not a namespace. Consider a ‘using static’ directive instead

Миниатюры

Ошибка CS0104 при использовании Random
 

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



293 / 215 / 85

Регистрация: 17.02.2016

Сообщений: 1,269

Записей в блоге: 1

23.08.2020, 12:51

2

скорее всего Рандом хочет инт а не флоат



0



epyskop

143 / 130 / 30

Регистрация: 26.07.2017

Сообщений: 633

23.08.2020, 14:17

3

У вас подключены две библиотеки System и UnityEngine, и там и там есть метод Random. Допишите там где используете Random.

C#
1
UnityEngine.Random.Range(-1,4f, 1,56f), UnityEngine.Random.Range(0,9f, 2,9f)



2



Erdinger

247 / 173 / 75

Регистрация: 04.07.2012

Сообщений: 711

23.08.2020, 14:35

4

C#
1
using Random = UnityEngine.Random;



1



293 / 215 / 85

Регистрация: 17.02.2016

Сообщений: 1,269

Записей в блоге: 1

23.08.2020, 14:39

5

Цитата
Сообщение от epyskop
Посмотреть сообщение

две библиотеки System и UnityEngine

да точно



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

23.08.2020, 14:39

5

Почему не работает рандом?

Почему не работает рандом?

хочу сделать рандом Random.Range(2f, 5f); но мне выдаёт две ошибки:
1) Assets/Controller.cs(64,62): error CS0104: `Random’ is an ambiguous reference between `UnityEngine.Random’ and `System.Random’
2) Assets/Controller.cs(64,62): error CS0103: The name `Random’ does not exist in the current context

Никак не пойму что не так.
E11.transform.position = new Vector3(Random.Range(2f, 5f), 3f, 5f);

Аватара пользователя
ZhuDen
UNIт
 
Сообщения: 82
Зарегистрирован: 20 июн 2012, 23:05

Re: Почему не работает рандом?

Сообщение ShyRec 29 сен 2013, 21:24

Он тебе пишет, что у компилятора когнитивный диссонанс, и он не поймёт из какого пространства имён ему брать рандом. Укажи конкретно, у меня тоже такое было.
Плюс ругается, что нет инициализации.
Вроде так.

ShyRec
UNIт
 
Сообщения: 140
Зарегистрирован: 23 май 2013, 13:02
Откуда: Астрахань

Re: Почему не работает рандом?

Сообщение ZhuDen 29 сен 2013, 21:26

ShyRec писал(а):Он тебе пишет, что у компилятора когнитивный диссонанс, и он не поймёт из какого пространства имён ему брать рандом. Укажи конкретно, у меня тоже такое было.
Плюс ругается, что нет инициализации.
Вроде так.

Так что именно сделать? О_о

Аватара пользователя
ZhuDen
UNIт
 
Сообщения: 82
Зарегистрирован: 20 июн 2012, 23:05

Re: Почему не работает рандом?

Сообщение ShyRec 29 сен 2013, 21:30

ZhuDen писал(а):

ShyRec писал(а):Он тебе пишет, что у компилятора когнитивный диссонанс, и он не поймёт из какого пространства имён ему брать рандом. Укажи конкретно, у меня тоже такое было.
Плюс ругается, что нет инициализации.
Вроде так.

Так что именно сделать? О_о

Используется csharp

using System.Random;
//или UnityEngine.Random

//……///

//и инициализируем, тобеж создаём объект класса
Random rnd = new Random();
//и юзаем
E11.transform.position = new Vector3(rnd.Range(2f, 5f), 3f, 5f);

если где не прав, извиняйте. сам-то нуб нубом :)

ShyRec
UNIт
 
Сообщения: 140
Зарегистрирован: 23 май 2013, 13:02
Откуда: Астрахань

Re: Почему не работает рандом?

Сообщение ZhuDen 29 сен 2013, 21:32

ShyRec писал(а):

ZhuDen писал(а):

ShyRec писал(а):Он тебе пишет, что у компилятора когнитивный диссонанс, и он не поймёт из какого пространства имён ему брать рандом. Укажи конкретно, у меня тоже такое было.
Плюс ругается, что нет инициализации.
Вроде так.

Так что именно сделать? О_о

Используется csharp

using System.Random;
//или UnityEngine.Random

//……///

//и инициализируем, тобеж создаём объект класса
Random rnd = new Random();
//и юзаем
E11.transform.position = new Vector3(rnd.Range(2f, 5f), 3f, 5f);

если где не прав, извиняйте. сам-то нуб нубом :)

using System.Random;
//или UnityEngine.Random
Никакое из них не работает, по прежнему ошибки, что делать?

Аватара пользователя
ZhuDen
UNIт
 
Сообщения: 82
Зарегистрирован: 20 июн 2012, 23:05

Re: Почему не работает рандом?

Сообщение ShyRec 29 сен 2013, 21:35

ZhuDen писал(а):

ShyRec писал(а):

ZhuDen писал(а):

ShyRec писал(а):Он тебе пишет, что у компилятора когнитивный диссонанс, и он не поймёт из какого пространства имён ему брать рандом. Укажи конкретно, у меня тоже такое было.
Плюс ругается, что нет инициализации.
Вроде так.

Так что именно сделать? О_о

Используется csharp

using System.Random;
//или UnityEngine.Random

//……///

//и инициализируем, тобеж создаём объект класса
Random rnd = new Random();
//и юзаем
E11.transform.position = new Vector3(rnd.Range(2f, 5f), 3f, 5f);

если где не прав, извиняйте. сам-то нуб нубом :)

using System.Random;
//или UnityEngine.Random
Никакое из них не работает, по прежнему ошибки, что делать?

Попробуй вместо этого сделать так

Используется csharp

System.Random rnd = new System.Random();
//и юзаем
E11.transform.position = new Vector3(rnd.Range(2f, 5f), 3f, 5f);

ShyRec
UNIт
 
Сообщения: 140
Зарегистрирован: 23 май 2013, 13:02
Откуда: Астрахань

Re: Почему не работает рандом?

Сообщение ZhuDen 29 сен 2013, 21:40

ShyRec писал(а):

ZhuDen писал(а):

ShyRec писал(а):

ZhuDen писал(а):

ShyRec писал(а):Он тебе пишет, что у компилятора когнитивный диссонанс, и он не поймёт из какого пространства имён ему брать рандом. Укажи конкретно, у меня тоже такое было.
Плюс ругается, что нет инициализации.
Вроде так.

Так что именно сделать? О_о

Используется csharp

using System.Random;
//или UnityEngine.Random

//……///

//и инициализируем, тобеж создаём объект класса
Random rnd = new Random();
//и юзаем
E11.transform.position = new Vector3(rnd.Range(2f, 5f), 3f, 5f);

если где не прав, извиняйте. сам-то нуб нубом :)

using System.Random;
//или UnityEngine.Random
Никакое из них не работает, по прежнему ошибки, что делать?

Попробуй вместо этого сделать так

Используется csharp

System.Random rnd = new System.Random();
//и юзаем
E11.transform.position = new Vector3(rnd.Range(2f, 5f), 3f, 5f);

System.Random rnd = new System.Random(); // Эта строка работает
//и юзаем
E11.transform.position = new Vector3(rnd.Range(2f, 5f), 3f, 5f); // А в вот этой ошибка:
Assets/Controller.cs(65,66): error CS1061: Type `System.Random’ does not contain a definition for `Range’ and no extension method `Range’ of type `System.Random’ could be found (are you missing a using directive or an assembly reference?)

Аватара пользователя
ZhuDen
UNIт
 
Сообщения: 82
Зарегистрирован: 20 июн 2012, 23:05

Re: Почему не работает рандом?

Сообщение ShyRec 29 сен 2013, 21:42

Так, извини. Вместо System.Random = new System.Random (); попробуй UnityEngine.Random = new UnityEngine.Random ();

ShyRec
UNIт
 
Сообщения: 140
Зарегистрирован: 23 май 2013, 13:02
Откуда: Астрахань

Re: Почему не работает рандом?

Сообщение ZhuDen 29 сен 2013, 21:46

ShyRec писал(а):Так, извини. Вместо System.Random = new System.Random (); попробуй UnityEngine.Random = new UnityEngine.Random ();

тоже самое =(

Аватара пользователя
ZhuDen
UNIт
 
Сообщения: 82
Зарегистрирован: 20 июн 2012, 23:05

Re: Почему не работает рандом?

Сообщение ShyRec 29 сен 2013, 21:49

Я уже даже не знаю. Честно говоря не использовал юнитековский рандом.

Используется csharp

using UnityEngine;
using System.Collections;
using UnityEngine.Random;

E11.transform.position = new Vector3(Random.Range(2f, 5f), 3f, 5f);

Всё, больше никаких догадок. :-?

ShyRec
UNIт
 
Сообщения: 140
Зарегистрирован: 23 май 2013, 13:02
Откуда: Астрахань

Re: Почему не работает рандом?

Сообщение ZhuDen 29 сен 2013, 21:51

ShyRec писал(а):Я уже даже не знаю. Честно говоря не использовал юнитековский рандом.

Используется csharp

using UnityEngine;
using System.Collections;
using UnityEngine.Random;

E11.transform.position = new Vector3(Random.Range(2f, 5f), 3f, 5f);

Всё, больше никаких догадок. :-?

=( Кто нибудь ещё знает? :|

Аватара пользователя
ZhuDen
UNIт
 
Сообщения: 82
Зарегистрирован: 20 июн 2012, 23:05

Re: Почему не работает рандом?

Сообщение Avatarchik 29 сен 2013, 22:08

Вместо using UnityEngine.Random; надо using Random = UnityEngine.Random; ;)

Добавить ava-karaban в Skype

Аватара пользователя
Avatarchik
UNITрон
 
Сообщения: 274
Зарегистрирован: 04 апр 2009, 15:36
Откуда: Украина(Донецк)
  • ICQ

Re: Почему не работает рандом?

Сообщение AndreyMust19 29 сен 2013, 22:46

Ну вы намудрили. Просто UnityEngine.Random.Range написать кто мешает?

Нужна помощь? Сами, сами, сами, сами, сами… делаем все сами

AndreyMust19
Адепт
 
Сообщения: 1119
Зарегистрирован: 07 июн 2011, 13:19

Re: Почему не работает рандом?

Сообщение mp3 29 сен 2013, 22:47

public class MyClass : MonoBehaviour {

Be straight, or go forward.

Аватара пользователя
mp3
Адепт
 
Сообщения: 1071
Зарегистрирован: 21 окт 2009, 23:50

Re: Почему не работает рандом?

Сообщение renegate-All 26 май 2020, 15:36

Убери из библиотек вначале using System;

renegate-All
UNец
 
Сообщения: 2
Зарегистрирован: 18 окт 2018, 16:46


Вернуться в Общие вопросы

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 10



Понравилась статья? Поделить с друзьями:
  • Unity error building player because scripts had compiler errors
  • Unity curl error 52 empty reply from server
  • Unity crash handler 32 как исправить
  • Unity bug reporter как исправить
  • Unity assets explorer stream read error