简体   繁体   中英

Can't build game because of ObjectNames.GetUniqueName, Unity

I'm building my game and after like 4 seconds there is an error that says: Assets\PlayerInventory.cs(228,37): error CS0103: The name 'ObjectNames' does not exist in the current context I'm using the function so that the objects don't all have the same name, but I can't build because of it. I'm using it like this:

string uniqueName = ObjectNames.GetUniqueName(names, ""); this is just adding a number on the end so it would be

Object
Object (1)
Object (2)

and so on...

Why is it not letting me build?

EDIT:

Code snippet:

using System.Collections;
using System.IO;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Linq;
using UnityEditor;
using Photon.Pun;
using UnityEngine.UI;

public class PlayerInventory : MonoBehaviour
{
    // Names taken
    public string[] names = new string[] { "Object" };
    
    void Start()
    {
         string uniqueName = ObjectNames.GetUniqueName(names, "");
    }
}

Some of the using are not needed for this snippet.

BecauseObjectNames is part of the namespaceUnityEditor which only exists within the Unity editor itself and is completely stripped of during the build process.

=> You can't use any of it in the actual released application, it is only for doing stuff within the editor itself.


Unfortunately the exact content of GetUniqueName is also not public in the source code but you can implement something similar yourself.

There might be better and more efficient ways but I would go with eg

public static class StringExtensions
{
    // Regex Matches a trailing indexer 
    // e.g. "Example (1)"
    private const string k_IndexMatch = " \\(([0-9]+)\\)$";

    private static bool HasIndexer(string name, out int? index, out string nameWithoutIndex)
    {
        var matches = Regex.Matches(name, k_IndexMatch);

        var nameIndexMatch = matches.LastOrDefault();
        // or in case of older Unity/c# version without Linq
        //var nameIndexMatch = matches.Count == 0 ? null : matches[matches.Count - 1]; 

        if (nameIndexMatch == null)
        {
            index = null;
            nameWithoutIndex = name;
            return false;
        }

        // First group is always entire match, we want only the numeric value which is the second group
        var group = nameIndexMatch.Groups[1];
        index = int.Parse(group.Value);
        nameWithoutIndex = name.Substring(0, name.Length - nameIndexMatch.Value.Length);

        return true;
    }

    public static string GetUniqueName(this string name, IEnumerable<string> existingNames)
    {
        HasIndexer(name, out var index, out var nameWithoutIndex);

        foreach (var existingName in existingNames)
        {
            if (existingName == nameWithoutIndex)
            {
                // Exact match (without index) 
                // in this case either keep your index or if there is none use 1
                if (index == null)
                {
                    index = 1;
                }

                continue;
            }

            if (HasIndexer(existingName, out var existingIndex, out var existingNameWithoutIndex))
            {
                if (existingNameWithoutIndex == nameWithoutIndex)
                {
                    index = index == null ? existingIndex + 1 : Math.Max(index.Value, existingIndex.Value + 1);
                }
            }
        }

        return nameWithoutIndex + (index == null ? "" : $" ({index})");
    }
}

See also .NetFiddle ( older c# )

Example usage

var uniqueName = "Example".GetUniqueName(new []{"Example 0", "Example (1)", "Nope", "Example", "Example (2)"});

=>

Example (3)

since only "Example (1)", "Example", "Example (2)" are overlapping matches and highest free index is 3 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM