Aracılığıyla paylaş


Kodlama yönergeleri

Bu belgede Unity için World Locking Tools için önerilen kodlama yönergeleri özetlenmiştir. Bu önerilerin çoğu MSDN'de önerilen standartlara uyar.


Betik lisans bilgileri üst bilgileri

Unity için World Locking Tools'a gönderilen tüm betiklerde, aşağıda gösterildiği gibi standart Lisans üst bilgisi eklenmelidir:

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

Lisans üst bilgisi olmadan gönderilen tüm betik dosyaları reddedilir.

İşlev / Yöntem özet üst bilgileri

Gönderilen tüm genel sınıflar, yapılar, sabit listeleri, işlevler, özellikler, alanlar amaçlarına ve kullanımlarına tam olarak aşağıda gösterildiği gibi açıklanmalıdır:

    /// <summary>
    /// The Controller definition defines the Controller as defined by the SDK / Unity.
    /// </summary>
    public struct Controller
    {
        /// <summary>
        /// The ID assigned to the Controller
        /// </summary>
        public string ID;
    }

Bu kural tüm sınıflar, yöntemler ve özellikler için belgelerin düzgün bir şekilde oluşturulmasını ve dağıtılmasını sağlar.

Düzgün özet etiketleri olmadan gönderilen tüm betik dosyaları reddedilir.

Ad alanı kuralları

Tüm sınıfların ve uzantıların kapsamı ad alanına göre belirlenmiş ve aşağıdaki ad alanları arasından uygun şekilde seçilmelidir.

Microsoft.MixedReality.WorldLocking.Core - Temel World Locking Tools hizmetini gerçekleştiren temel kod.

Microsoft.MixedReality.WorldLocking.Tools - Dünya Kilitleme Araçları'nın üzerinde geliştirmeyi tamamlayan isteğe bağlı özellikler. Örnek olarak tanılama görselleştirmeleri ve uygulama olay işleyicilerinin temel uygulamaları verilebilir.

Microsoft.MixedReality.WorldLocking.Examples - World Locking Tools özelliklerinin nasıl kullanılacağını ve elde edilen avantajları gösteren belirli uygulamalar.

Yukarıdaki ad alanlarının içindeki ilgili özellikler, yeni bir alt ad alanına genişletilerek gruplandırılabilir.

Yapın

namespace Microsoft.MixedReality.WorldLocking.Examples.Placement
{
    // Interface, class or data type definition.
}

Bir arabirim, sınıf veya veri türü için ad alanının atlanması, değişikliğinizin engellenmesine neden olur.

Boşluklar ve Sekmeler karşılaştırması

Bu projeye katkıda bulunurken sekme yerine dört boşluk kullandığınızdan emin olun.

Ayrıca, if / while / for gibi koşullu / döngü işlevleri için boşluklar eklendiğinden emin olun

Yapmayın

private Foo () // < - space between Foo and ()
{
    if(Bar==null) // <- no space between if and ()
    {
        DoThing();
    }
    
    while(true) // <- no space between while and ()
    {
        Do();
    }
}

Yapın

private Foo()
{
   if (Bar==null)
   {
       DoThing();
   }
   
   while (true)
   {
       Do();
   }
}

Aralık

Köşeli ayraçlarla parantez arasına ek boşluk eklemeyin:

Yapmayın

private Foo()
{
    int[ ] var = new int [ 9 ];
    Vector2 vector = new Vector2 ( 0f, 10f );
}

Yapın

private Foo()
{
    int[] var = new int[9];
    Vector2 vector = new Vector2(0f, 10f);
}

Adlandırma Kuralları

Her zaman genel / korumalı / sanal özellikler ve camelCase özel özellikler ve alanlar için kullanınPascalCase.

Bunun tek istisnası, alanların tarafından serileştirilmesini gerektiren veri yapılarıdır JsonUtility.

Yapmayın

public string myProperty; // <- Starts with a lower case letter
private string MyProperty; // <- Starts with an uppercase case letter

Yapın

public string MyProperty;
protected string MyProperty;
private string myProperty;

Erişim Değiştiricileri

Her zaman tüm alanlar, özellikler ve yöntemler için bir erişim değiştirici bildirin.

Türetilmiş bir sınıfta geçersiz kılmanız gerekmediği sürece tüm Unity API Yöntemleri varsayılan olarak olmalıdır private . Bu durumda protected kullanılmalıdır.

Alanlar her zaman privateveya protected özellik erişimcileriyle olmalıdırpublic.

Yapmayın

// protected field should be private
protected int myVariable = 0;

// property should have protected setter
public int MyVariable { get { return myVariable; } }

// No public / private access modifiers
void Foo() { }
void Bar() { }

Yapın

public int MyVariable { get; protected set; } = 0;

private void Foo() { }
public void Bar() { }
protected virtual void FooBar() { }

Küme Ayraçlarını Kullanma

Her deyim bloğundan sonra her zaman ayraç kullanın ve bunları bir sonraki satıra yerleştirin.

Yapmayın

private Foo()
{
    if (Bar==null) // <- missing braces surrounding if action
        DoThing();
    else
        DoTheOtherThing();
}

Yapmayın

private Foo() { // <- Open bracket on same line
    if (Bar==null) DoThing(); <- if action on same line with no surrounding brackets 
    else DoTheOtherThing();
}

Yapın

private Foo()
{
    if (Bar==true)
    {
        DoThing();
    }
    else
    {
        DoTheOtherThing();
    }
}

Genel sınıfların, yapıların ve sabit listelerin tümü kendi dosyalarına girmelidir.

Sınıf, yapı veya sabit listesi özel hale getirilebiliyorsa, aynı dosyaya dahil edilmesi sorun olmaz. Bu ekleme Unity ile ilgili derleme sorunlarını önler ve doğru kod soyutlamanın oluşmasını sağlar. Ayrıca kodun değiştirilmesi gerektiğinde çakışmaları ve hataya neden olan değişiklikleri azaltır.

Yapmayın

public class MyClass
{
    public struct MyStruct() { }
    public enum MyEnumType() { }
    public class MyNestedClass() { }
}

Yapın

// Private references for use inside the class only
public class MyClass
{
   private struct MyStruct() { }
   private enum MyEnumType() { }
   private class MyNestedClass() { }
}

Yapın

MyStruct.cs

// Public Struct / Enum definitions for use in your class.  Try to make them generic for reuse.
public struct MyStruct
{
   public string Var1;
   public string Var2;
}

MyEnumType.cs

public enum MuEnumType
{
    Value1,
    Value2 // <- note, no "," on last value to denote end of list.
}

MyClass.cs

public class MyClass
{
    private MyStruct myStructreference;
    private MyEnumType myEnumReference;
}

Uygun uzantı için Enum'ları sırala.

Bir Sabit Listesi'nin gelecekte genişletilme olasılığı varsa, varsayılan değerleri Enum'un en üstünde sıralamak için kritik önem taşır. Bu sıralama, Numaralandırma dizinlerinin yeni eklemelerden etkilenmemesini sağlar.

Yapmayın

public enum SDKType
{
    WindowsMR,
    OpenVR,
    OpenXR,
    None, <- default value not at start
    Other <- anonymous value left to end of enum
}

Yapın

   /// <summary>
   /// The SDKType lists the VR SDK's that are supported by the MRTK
   /// Initially, this lists proposed SDK's, not all may be implemented at this time (please see ReleaseNotes for more details)
   /// </summary>
   public enum SDKType
   {
       /// <summary>
       /// No specified type or Standalone / non-VR type
       /// </summary>
       None = 0,
       /// <summary>
       /// Undefined SDK.
       /// </summary>
       Other,
       /// <summary>
       /// The Windows 10 Mixed reality SDK provided by the Universal Windows Platform (UWP), for Immersive MR headsets and HoloLens. 
       /// </summary>
       WindowsMR,
       /// <summary>
       /// The OpenVR platform provided by Unity (does not support the downloadable SteamVR SDK).
       /// </summary>
       OpenVR,
       /// <summary>
       /// The OpenXR platform. SDK to be determined once released.
       /// </summary>
       OpenXR
   }

"Tür" ile Bitiş Sabit Listesi adları

Sabit listesi adları, Tür sonekini kullanarak doğalarını açıkça belirtmelidir.

Yapmayın

public enum Ordering
{
    First,
    Second,
    Third
}
public enum OrderingEnum
{
    First,
    Second,
    Third
}

Yapın

public enum OrderingType
{
    First = 0,
    Second,
    Third
}

Bitalanları için Numaralandırma kullanımını gözden geçirin

Bir sabit listesi için değer olarak birden çok durum gerektirebilir, örneğin, Handedness = Sol & Sağ. Ardından Enum'un doğru şekilde kullanılabilmesi için BitFlags ile dekore edilmesi gerekir

Handedness.cs dosyasında bunun için somut bir uygulama vardır

Yapmayın

public enum Handedness
{
    None,
    Left,
    Right
}

Yapın

[flags]
public enum HandednessType
{
   None = 0 << 0,
   Left = 1 << 0,
   Right = 1 << 1,
   Both = Left | Right
}

Unity önerileri de dahil olmak üzere En İyi Yöntemler

Bu projenin hedef platformlarından bazılarının performansı dikkate alması gerekir. Bunu göz önünde bulundurarak, sıkı güncelleştirme döngülerinde veya algoritmalarda sık kullanılan kodda bellek ayırırken her zaman dikkatli olun.

Kapsülleme

Sınıf veya yapının dışından alana erişim gerekiyorsa her zaman özel alanları ve genel özellikleri kullanın. Özel alanı ve ortak özelliği birlikte bulmayı unutmayın. Bu konum, özelliğin neleri yedeklediğini ve alanın betikle değiştirilebiliyor olduğunu bir bakışta görmeyi kolaylaştırır.

Denetçide alanınızı düzenleyebilmeniz gerekiyorsa, Encapsulation kurallarına uymanız ve yedekleme alanınızı seri hale getirmeniz en iyi yöntemdir.

Bunun tek istisnası, alanların tarafından JsonUtilityseri hale getirilmesini gerektiren veri yapılarıdır. Burada, serileştirmenin çalışması için bir veri sınıfının tüm genel alanlara sahip olması gerekir.

Yapmayın

public float MyValue;

Yapın

// private field, only accessible within script (field is not serialized in Unity)
private float myValue;

Yapın

// Enable private field to be configurable only in editor (field is correctly serialized in Unity)
[SerializeField] 
private float myValue;

Yapmayın

private float myValue1;
private float myValue2;

public float MyValue1
{
    get{ return myValue1; }
    set{ myValue1 = value }
}

public float MyValue2
{
    get{ return myValue2; }
    set{ myValue2 = value }
}

Yapın

// Enable field to be configurable in the editor and available externally to other scripts (field is correctly serialized in Unity)
[SerializeField]
[ToolTip("If using a tooltip, the text should match the public property's summary documentation, if appropriate.")]
private float myValue; // <- Notice we co-located the backing field above our corresponding property.

/// <summary>
/// If using a tooltip, the text should match the public property's summary documentation, if appropriate.
/// </summary>
public float MyValue
{
    get{ return myValue; }
    set{ myValue = value }
}

Mümkün olduğunda yerine foreach kullanın for

Bazı durumlarda, örneğin bir IEnumerable üzerinden döngü yaparken bir foreach gereklidir. Ancak performans avantajı için, uygun olduğunda foreach kullanmaktan kaçının.

Yapmayın

foreach(var item in items)

Yapın

int length = items.length; // cache reference to list/array length
for(int i=0; i < length; i++)

Mümkün olduğunda değerleri önbelleğe alın ve sahne/ön bellekte serileştirin.

HoloLens'i göz önünde bulundurarak, çalışma zamanı bellek ayırmalarını sınırlamak için sahne veya ön bellek başvurularını iyileştirmek en iyisidir.

Yapmayın

void Update()
{
    gameObject.GetComponent<Renderer>().Foo(Bar);
}

Yapın

[SerializeField] // To enable setting the reference in the inspector.
private Renderer myRenderer;

private void Awake()
{
   // If you didn't set it in the inspector, then we cache it on awake.
   if (myRenderer == null)
   {
       myRenderer = gameObject.GetComponent<Renderer>();
   }
}

private void Update()
{
   myRenderer.Foo(Bar);
}

Malzemelere yapılan başvuruları önbelleğe alın, her seferinde ".material" çağırmayın.

Unity, her ".material" kullandığınızda yeni bir malzeme oluşturur ve bu da düzgün temizlenmediği takdirde bellek sızıntısına neden olur.

Yapmayın

public class MyClass
{
    void Update() 
    {
        Material myMaterial = GetComponent<Renderer>().material;
        myMaterial.SetColor("_Color", Color.White);
    }
}

Yapın

// Private references for use inside the class only
public class MyClass
{
   private Material cachedMaterial;

   private void Awake()
   {
       cachedMaterial = GetComponent<Renderer>().material;
   }

   void Update() 
   {
       cachedMaterial.SetColor("_Color", Color.White);
   }
   
   private void OnDestroy()
   {
       Destroy(cachedMaterial);
   }
}

Alternatif olarak, Unity'nin her başvuruda yeni bir malzeme oluşturmayan "SharedMaterial" özelliğini kullanın.

Toolkit'in başka bir platformdaki derlemeyi bozmayacağından emin olmak için platforma bağımlı derlemeyi kullanma

  • UWP'ye özgü, Unity olmayan API'leri kullanmak için kullanın WINDOWS_UWP . Bu tanım, Düzenleyici'de veya desteklenmeyen platformlarda çalışmaya çalışmalarını engeller. Bu tanım ile UNITY_WSA && !UNITY_EDITOR eşdeğerdir ve bunun yerine kullanılmalıdır.
  • Ad alanı gibi UWP'ye özgü Unity API'lerini UnityEngine.XR.WSA kullanmak için kullanınUNITY_WSA. Bu, platform UWP olarak ayarlandığında ve yerleşik UWP uygulamalarında Düzenleyici'de çalışır.

Bu grafik, kullanım örneklerinize ve beklediğiniz derleme ayarlarına bağlı olarak hangisini #if kullanacağınıza karar vermenize yardımcı olabilir.

Tanımlama UWP IL2CPP UWP .NET Düzenleyici
UNITY_EDITOR False Yanlış Doğru
UNITY_WSA True True True
WINDOWS_UWP True Doğru Yanlış
UNITY_WSA && !UNITY_EDITOR Doğru Doğru Yanlış
ENABLE_WINMD_SUPPORT Doğru Doğru Yanlış
NETFX_CORE Yanlış Doğru Yanlış

DateTime.Now yerine DateTime.UtcNow'u tercih edin

DateTime.UtcNow, DateTime.Now değerinden daha hızlıdır. Önceki performans araştırmalarında DateTime.Now kullanmanın özellikle Update() döngüsünde kullanıldığında önemli ek yük eklediğini tespit ettik. Diğerleri de aynı soruna çarptı.

Yerelleştirilmiş saatlere gerçekten ihtiyacınız yoksa DateTime.UtcNow kullanmayı tercih edin (geçerli bir neden kullanıcının saat diliminde geçerli saati göstermek istemeniz olabilir). Göreli sürelerle ilgileniyorsanız (yani, son güncelleştirmelerle şimdi arasındaki değişim), saat dilimi dönüştürmeleri yapma yükünden kaçınmak için DateTime.UtcHükümlü kullanmak en iyisidir.