Я знаю, что этот вопрос задавали по поводу других вкусов, но я не нашел своего... извините, если дублирую.
У меня есть функция, которая внутренне использует класс Time
и его свойства, как, например, deltaTime
.
Чтобы отладить свою функцию, я хотел бы использовать не класс Time
как есть, а его производный класс TimeDebug : Time
и переопределить свойство deltaTime
, превратив его во что-то предсказуемое, т.е.:
public class TimeDebug : Time
{
public static new float deltaTime { get { return 0.2f; } }
}
Моя функция будет использовать класс как полиморфный параметр:
void DoSomething(TimeDebug timer)
{
...
...
}
Моя функция может получить параметр Time
или TimeDebug
, в зависимости от «Режима выпуска» или «Режима отладки»:
DoSomething(new TimerDebug()) // debug mode
DoSomething(new Timer()) // release mode
Теперь возникает вопрос: компилятор не позволит мне скомпилировать доступ для чтения к статическому члену deltaTime
, потому что я делаю это из экземпляра класса. Например, я не могу сделать:
void DoSomething(TimeDebug timer)
{
Debug.Log(timer.deltaTime); // won't compile!!
}
Как передать параметр класса, чтобы я мог прочитать свойство deltaTime
, независимо от того, равен ли параметр класса Time
или TimeDebug
?
🤔 А знаете ли вы, что...
С C# можно разрабатывать веб-приложения с использованием ASP.NET и ASP.NET Core.
Я чувствую, что это проблема XY. На самом деле вас не волнует «получение статического свойства через экземпляр», вы пытаетесь исправить deltaTime
до определенного значения в Unity (условно).
Это можно сделать, просто установив для Time.captureDeltaTime значение 0,2f:
Если это свойство имеет ненулевое значение, то Time.time увеличивается с интервалом captureDeltaTime (масштабируемым Time.timeScale) независимо от реального времени и продолжительности кадра. Это полезно, если вы хотите снять фильм, в котором вам нужна постоянная частота кадров и вы хотите оставить достаточно времени между кадрами для сохранения изображений на экране.
Очевидно, что из-за того, что вы блокируете deltaTime
без блокировки частоты кадров, игра будет работать СЛИШКОМ быстро для большинства компьютеров. (1 секунда реального времени при 200 кадрах в секунду будет 0.2 (deltaTime) * 200 (frames)
= 40 секундам игрового времени)
Что касается того, почему это называется «captureDeltaTime
»; он предназначен в основном для «захвата» видео игрового процесса как можно быстрее, без учета того, как оно выглядит в реальном времени. Похоже на то, что видеоредакторы при рендеринге просматривают видео намного быстрее, чем в реальном времени.
Решение «Y»-части проблемы XY: вы не можете переопределить статическое свойство, поскольку статические свойства не могут быть виртуальными.
Лучшее, что вы можете сделать, это создать новый класс, который имеет собственное нестатическое свойство virtual float deltaTime
, и создать два дочерних класса, которые наследуются от него: один возвращает Time.deltaTime
, а другой возвращает 0.2f
; затем перейдите в эти классы:
public class Timer {
public virtual float deltaTime => Time.deltaTime;
}
public class DebugTimer : Timer {
public override float deltaTime => 0.2f;
}
Затем вы можете просто передать экземпляр Timer
:
void DoSomething(Timer timer)
{
Debug.Log(timer.deltaTime);
}
Обобщенным решением было бы предоставить Time(r) (какой из них?) виртуальное нестатическое свойство, которое может быть переопределено производным классом:
public class TimeDebug : Time
{
public static new float deltaTime { get { return 0.2f; } }
public override float DeltaTime => deltaTime;
}
Использование соглашений об именах для указания обоих видов доступа может вызывать опасения (может быть даже сомнительно вообще иметь статическое свойство, в зависимости от вашего использования), но это «правильный» способ запроса свойства, привязанного к конкретному экземпляр класса, который будет запрошен методами. Другие, более загадочные реализации могут включать в себя предоставление таймеру обобщенного свойства DeltaTime, которое использует отражение ссылки «this» для поиска фактического значения статического свойства «deltaTime», но я не думаю, что здесь это имеет большой смысл.