2016-04-15 2 views
1

Мне нужна помощь в понимании присвоения переменных с языком C#.Переменное назначение и Unity

При написании сценариев с Monodevelop for Unity я назначаю компоненты RigidBody и Collider (среди прочих) игровых объектов для локальных переменных. Когда я изменяю эти переменные, вызывая их методы или изменяя их атрибуты, эти изменения отражаются в исходных компонентах. Для того, чтобы моя точка яснее я оставлю этот псевдо-код ниже:

void someMethod(Rigidbody rb) 
{ 
    Rigidbody localRigidBody; 
    localRigidBody = rb; //assigned external rb component to local rigidBody 
    localRigidBody.velocity = 10.0f; //changes are reflected in the original rb object! 
} 

Что меня смущает, являются изменения в игровом объекте, который «содержит» ПУЭ Rigibody компонент. Хотя я знаю, что это работает, в виду это не должно работать, потому что localRigidBody является локальной переменной, а изменение скорости localRigidBody не должно изменять значение скорости rb. Но он изменяется, и он работает, поскольку объект с компонентом rb меняет свою скорость при запуске моей программы. Можете ли вы объяснить мне, почему?

Пожалуйста, сообщите мне, если мой вопрос не выяснен, и я постараюсь выразить себя лучше.

спасибо.

+0

Думай переменной как указатель на область памяти. Память содержит поля и свойства экземпляра. Если у вас есть 2 переменные, и вы назначаете 'a'' b', все, что вы делаете, это установка указателей в один и тот же раздел памяти. Следовательно, если вы измените память, на которую они указывают, они оба будут иметь одно и то же новое значение. –

+0

@RB, поэтому все переменные в C# являются указателями? Спасибо за ваш ответ. – Dayman75

+0

Ваш 'localRigidBody' в этом случае будет ссылкой на это жесткое тело, а не на копию. Помимо некоторых кеширующих материалов и т. Д. Это можно рассматривать как некоторое качество жизни, потому что вместо того, чтобы делать что-то вроде 'rb.AddForce', вам всегда приходилось писать что-то вроде GameObject.FindWithTag (« Foo »). GetComponent () .AddForce() '. –

ответ

2

Unity проходит это Rigidbody по справке. Если вы хотите copy или clone из Rigidbody, что совершенно не зависит от исходного объекта (rb), который был передан в ваш метод можно использовать Instantiate:

void someMethod(Rigidbody rb) 
{ 
    Rigidbody localRigidBody = Instantiate<Rigidbody>(rb); 
    localRigidBody.velocity = 10.0f; 
} 

В противном случае в вашем оригинале, как указано @RB, ваш localRigidBody это просто «псевдоним» исходной переменной rb, поскольку оба они указывают на один и тот же объект (расположение памяти).

Посмотрите этот SO вопрос/ответ, чтобы понять, что, проходя мимо «ссылки» является: Passing Objects By Reference or Value in C#

Update:

Что делать, если я создаю простой сценарий, где я объявить переменную «ИНТ а = 10 ;» а затем «int b = a», за которым следует «b = 8». Будет ли «а» изменить свою ценность? Или же «b» тоже есть псевдоним?

Примитивные типы данных обрабатываются немного по-другому ;-) Я бы посоветовал сделать некоторые исследования по примитивным по сравнению с ссылочными типами, Microsoft имеет некоторые большие статьи относительно этого ... ваш пример:

Код:

int a = 10; 
Console.WriteLine (a); 
int b = a; 
Console.WriteLine (b); 
b = 8; 
Console.WriteLine (a); 
Console.WriteLine (b); 

Выход:

10 
10 
10 
8 
Press any key to continue... 
+0

Спасибо за ваше время :) Еще один вопрос, если у вас есть время: Что делать, если я создаю простой скрипт, где я объявляю переменную «int a = 10;» а затем «int b = a», за которым следует «b = 8». Будет ли «а» изменить свою ценность? Или же «b» тоже есть псевдоним? Спасибо. – Dayman75

+0

@ Dayman75, проверьте мой ответ, я обновил его – SushiHangover

+1

Довольно немного усилий :) Спасибо за ваше время. – Dayman75

0

Вы просто споткнулся о фундаментальной "особенность" наиболее программирования Лос-Анджелеса nguages.

Есть два способа передать переменную вокруг:

Пасс ссылки

В объектах C# передаются по ссылке. Это означает, что когда вы назначаете уже существующий объект (например, ваш Rigidbody rb) переменной (ваш localRigidBody), вы создаете новый объект , а не.Вместо этого ваш localRigidBody - это всего лишь ссылка на rb. Если вы хотите создать независимую копию rb, вам нужно «клонировать» ее.

Пасс значение

типы, как int или double передаются по значению. Вы всегда будете получать свежую и независимую копию переданного параметра.

Я хотел бы предложить вам начать с чтения msdn article

+0

Получил это. Ваш ответ проделал потрясающую работу. Спасибо :) – Dayman75

+1

@ Dayman75 Я не думаю, что кто-то действительно ответил на вопрос. в единстве ** классы ** передаются по ссылке. ** структуры ** передаются как значение. это абсолютная основа среды. – Fattie