unity5没有unity3d 弹出输入框框是什么情况

1856人阅读
3.3 Unity(49)
看到一个不错的编辑器路径设置输入框,前后都有文本提示,输入只在中间进行输入。效果如下所示:
默认的时候:
输入的时候:
代码如下:
using UnityE
using UnityE
public class TestWindow : EditorWindow
[MenuItem("Tools/Test")]
static void Init()
var window = EditorWindow.GetWindow&TestWindow&();
window.titleContent.text = "路径设置";
window.Show();
private string m_P
void OnGUI()
EditorGUILayout.LabelField("Path:");
m_Path = RelativeAssetPathTextField(m_Path, ".prefab");
public static GUIStyle TextFieldRoundE
public static GUIStyle TextFieldRoundEdgeCancelB
public static GUIStyle TextFieldRoundEdgeCancelButtonE
public static GUIStyle TransparentTextF
private string RelativeAssetPathTextField(string path, string extension)
if (TextFieldRoundEdge == null)
TextFieldRoundEdge = new GUIStyle("SearchTextField");
TextFieldRoundEdgeCancelButton = new GUIStyle("SearchCancelButton");
TextFieldRoundEdgeCancelButtonEmpty = new GUIStyle("SearchCancelButtonEmpty");
TransparentTextField = new GUIStyle(EditorStyles.whiteLabel);
TransparentTextField.normal.textColor = EditorStyles.textField.normal.textC
Rect position = EditorGUILayout.GetControlRect();
GUIStyle textFieldRoundEdge = TextFieldRoundE
GUIStyle transparentTextField = TransparentTextF
GUIStyle gUIStyle = (path != "") ? TextFieldRoundEdgeCancelButton : TextFieldRoundEdgeCancelButtonE
position.width -= gUIStyle.fixedW
if (Event.current.type == EventType.Repaint)
GUI.contentColor = (EditorGUIUtility.isProSkin ? Color.black : new Color(0f, 0f, 0f, 0.5f));
textFieldRoundEdge.Draw(position, new GUIContent("Assets/"), 0);
GUI.contentColor = Color.
Rect rect =
float num = textFieldRoundEdge.CalcSize(new GUIContent("Assets/")).x - 2f;
rect.y += 1f;
rect.width -=
EditorGUI.BeginChangeCheck();
path = EditorGUI.TextField(rect, path, transparentTextField);
if (EditorGUI.EndChangeCheck())
path = path.Replace('\\', '/');
if (Event.current.type == EventType.Repaint)
Rect position2 =
float num2 = transparentTextField.CalcSize(new GUIContent(path + ".")).x - EditorStyles.whiteLabel.CalcSize(new GUIContent(".")).x; ;
position2.x += num2;
position2.width -= num2;
GUI.contentColor = (EditorGUIUtility.isProSkin ? Color.black : new Color(0f, 0f, 0f, 0.5f));
EditorStyles.label.Draw(position2, extension, false, false, false, false);
GUI.contentColor = Color.
position.x += position.
position.width = gUIStyle.fixedW
position.height = gUIStyle.fixedH
if (GUI.Button(position, GUIContent.none, gUIStyle) && path != "")
path = "";
GUI.changed = true;
GUIUtility.keyboardControl = 0;
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3086173次
积分:32580
积分:32580
排名:第131名
原创:391篇
转载:88篇
评论:3344条
联系方式:
(2)(1)(1)(1)(1)(1)(1)(1)(1)(1)(3)(1)(1)(1)(1)(1)(1)(1)(2)(1)(1)(1)(1)(1)(3)(1)(1)(1)(1)(2)(1)(3)(3)(3)(1)(1)(3)(1)(1)(8)(1)(3)(2)(2)(3)(2)(3)(2)(1)(1)(2)(3)(6)(1)(4)(3)(1)(3)(5)(5)(5)(5)(1)(3)(5)(4)(4)(4)(5)(5)(1)(13)(11)(7)(5)(2)(5)(4)(5)(2)(7)(14)(18)(23)(19)(5)(35)(22)(21)(8)(10)(42)(49)I use a FiledInput in android app and when I starting to put string in it a softkeyboard pops up and a box, I want to get rid of it.
Is it any way to do so using Unity3d 4.6.2f1 ?
解决方案 You can use
本文地址: &
我在Android应用程序使用 FiledInput ,当我开始把字符串中有一个 softkeyboard 弹出,一个箱子,我想摆脱它。 它是没有办法做到这样使用 Unity3d 4.6.2f1 ?
解决方案 您可以使用的。
本文地址: &
扫一扫关注官方微信  首先要认清一点,Unet是服务器权威的。这在同步问题中很是重要。
  状态同步是从服务器向客户端方向上的。本地客户端没有序列化的数据,因为它和服务器共享同一个场景。任何为本地客户端序列化的数据都是多余的。然而,SyncVar钩子函数会被本地客户端调用。注意数据不会从客户端向服务器同步,这个方向上的操作叫做命令(Commands)。
  除了可以直接用的network类的同步组件,我们还应该认识几个操作:
同步变量[SyncVar]--
   同步变量是NetworkBehaviour脚本中的成员变量,他们会从服务器同步到客户端上。当一个物体被派生出来之后,或者一个新的玩家中途加入游戏后,他会接收到他的视野内所有物体的同步变量。成员变量通过[SyncVar]标签被配置成同步变量:
class Player :NetworkBehaviour{[SyncVar]public void TakeDamage(int amount){if (!isServer)health -=}}  同步变量的状态在OnStartClient()之前就被应用到物体上了,所以在OnStartClient中,物体的状态已经是最新的数据。  同步变量可以是基础类型,如整数,字符串和浮点数。也可以是Unity内置数据类型,如Vector3和用户自定义的结构体,但是对结构体类型的同步变量,如果只有几个字段的数值有变化,整个结构体都会被发送。每个NetworkBehaviour脚本可以有最多32个同步变量,包括同步列表(见下面的解释)。  当同步变量有变化时,会自动发送他们的最新数据。不需要手工为同步变量设置任何的脏数据位。  注意在属性设置函数中设置一个同步变量的值不会使他的脏数据被设置。如果这样做的话,会得到一个编译期的警告。因为同步变量使用他们自己内部的记录脏数据状态,在属性设置函数中设置脏位会引起递归调用问题。
  同步变量还可以指定函数,使用hook:
  当服务器改变了playerName的值,客户端会调用OnMyName这个函数[SyncVar(hook = "OnMyName")]public string playerName = "";
public void OnMyName(string newName){&&&&&&&&&&& playerName = newN&&&&&&&&&&& nameInput.text = playerN}
  同步列表(SyncLists)--
  同步列表类似于同步变量,但是他们是一些值的列表而不是单个值。同步列表和同步变量都包含在初始的状态更新里。同步列表不需要[SyncVar]属性,他们是特殊的类。内建的基础类型属性列表有:SyncListStringSyncListFloatSyncListIntSyncListUIntSyncListBool  还有个SyncListStruct可以给用户自定义的结构体用。从SyncListStruct派生出的结构体类可以包含基础类型,数组和通用Unity类型的成员变量,但是不能包含复杂的类和通用容器。    同步列表有一个叫做SyncListChanged的回调,可以使客户端能接收到列表中的数据改动的通知。这个回调函数被调用时,会被通知到操作类型,和修改的变量索引。public class MyScript :NetworkBehaviour{public struct Buf{};public class TestBufs : SyncListStruct&Buf& {}TestBufs m_bufs = new TestBufs();void BufChanged(Operation op, int itemIndex){Debug.Log("buf changed:" + op);}void Start(){m_bufs.Callback = BufC}}
定制序列化函数--
  通常在脚本中使用同步变量就够了,但是有时候也需要更复杂的序列化代码。NetworkBehaviour中的虚函数允许开发者定制自己的序列化函数,这些函数有:public virtual boolOnSerialize(NetworkWriter writer, bool initialState);public virtual voidOnDeSerialize(NetworkReader reader, bool initialState);  initalState可以用来是第一次序列化数据还是只发送增量的数据。如果是第一次发送给客户端,必须要包含所有状态的数据,后续的更新只需要包含增量的修改,以节省带宽。同步变量的钩子函数在initialState为True的时候不会被调用,而只会在增量更新函数中被调用。  如果一个类里面了同步变量,这些的实现会自动被加到类里面,因此一个有同步变量的类不能拥有自己的序列化函数。  OnSerialize函数应该返回True来指示有更新需要发送,如果它返回了true,这个类的所有脏位都会被清除,如果它返回False,则脏标志位不会被修改。这可以允许将多次改动合并在一起发送,而不需要每一帧都发送。&
序列化流程--
  具有NetworkIdentity组件的物体可以带有多个从NetworkBehaviour派生出来的脚本,这些物体的序列化流程为:在服务器上:- 每个NetworkBehaviour上都有一个脏数据掩码,这个掩码可以在OnSerialize函数中通过syncVarDirtyBits访问到- NetworkBehavious中的每个同步变量被指定了脏数据掩码中的一位- 对同步变量的修改会使对应的脏数据位被设置- 或者可以通过调用SetDirtyBit直接修改脏数据位-&的每个Update调用都会检查他的NetworkIdentity组件- 如果有标记为脏的NetworkBehaviour,就会为那个物体创建一个更新数据包- 每个NetworkBehaviour组件的OnSerialize都被调用,来构建这个更新数据包- 没有脏数据位设置的NetworkBehaviour在数据包中添加0标志- 有脏数据位设置的NetworkBehavious写入他们的脏数据和有改动的同步变量的值- 如果一个NetworkBehavious的OnSerialize函数返回了True,那么他的脏位被重置,因此直到下一次数据修改之前不会被再次发送- 更新数据包被发送到能看见这个物体的所有客户端在客户端:- 接收到一个物体的更新数据包- 每个NetworkBehavious脚本的OnDeserialize被调用- 这个物体上的每个NetworkBehavious脚本读取脏数据- 如果关联到这个NetworkBehaviour脚本的脏数据位是0,OnDeserialize函数直接返回;- 如果脏数据不是0,OnDeserialize函数继续读取后续的同步变量- 如果有同步变量的钩子,调用钩子函数对下面的代码:public class data :NetworkBehaviour{[SyncVar]public int int1 = 66;[SyncVar]public int int2 = 23487;[SyncVar]public string MyString = "esfdsagsdfgsdgdsfg";}产生的序列化OnSerialize将如下所示:public override boolOnSerialize(NetworkWriter writer, bool forceAll){if (forceAll){// 第一次发送物体信息给客户端,发送全部数据writer.WritePackedUInt32((uint)this.int1);writer.WritePackedUInt32((uint)this.int2);writer.Write(this.MyString);}bool wroteSyncVar =if ((base.get_syncVarDirtyBits() & 1u) != 0u){if (!wroteSyncVar){// write dirty bits if this is the first SyncVar writtenwriter.WritePackedUInt32(base.get_syncVarDirtyBits());wroteSyncVar =}writer.WritePackedUInt32((uint)this.int1);}if ((base.get_syncVarDirtyBits() & 2u) != 0u){if (!wroteSyncVar){// write dirty bits if this is the first SyncVar writtenwriter.WritePackedUInt32(base.get_syncVarDirtyBits());wroteSyncVar =}writer.WritePackedUInt32((uint)this.int2);}if ((base.get_syncVarDirtyBits() & 4u) != 0u){if (!wroteSyncVar){// write dirty bits if this is the first SyncVar writtenwriter.WritePackedUInt32(base.get_syncVarDirtyBits());wroteSyncVar =}writer.Write(this.MyString);}if (!wroteSyncVar){// write zero dirty bits if no SyncVars were writtenwriter.WritePackedUInt32(0);}return wroteSyncV}反序列化将如下:public override voidOnDeserialize(NetworkReader reader, bool initialState){if (initialState){this.int1 = (int)reader.ReadPackedUInt32();this.int2 = (int)reader.ReadPackedUInt32();this.MyString = reader.ReadString();}int num = (int)reader.ReadPackedUInt32();if ((num & 1) != 0){this.int1 = (int)reader.ReadPackedUInt32();}if ((num & 2) != 0){this.int2 = (int)reader.ReadPackedUInt32();}if ((num & 4) != 0){this.MyString = reader.ReadString();}}  如果这个NetworkBehaviour的基类也有一个序列化,基类的序列化函数也将被调用。  注意更新数据包可能会在缓冲区中合并,所以一个传输层数据包可能包含多个物体的更新数据包。
远程动作--
  网络系统允许在网络上执行远程的动作。这类动作有时也叫做远程过程调用(RPC)。有两种类型的远程过程调用,命令(Commands) & 由客户端发起,运行在服务器上;和客户端远程过程调用(ClientRpc) - 服务器发起,运行在客户端上。
命令(Commands)--
  命令从客户端上的物体发给上的物体。出于安全考虑,命令只能从控制的物体上发出,因此不能控制其他玩家的物体。要把一个函数变成命令,需要给这个函数添加[Command]属性,并且为函数名添加&Cmd&前缀,这样这个函数会在客户端上被调用时在上运行。所有的参数会自动和命令一起发送给服务器。  命令的名字必须要有&Cmd&前缀。在阅读代码的时候,这也是个提示 & 这个比较特殊,他不像普通函数一样在本地被执行。class Player :NetworkBehaviour{public GameObject bulletP[Command]void CmdDoFire(float lifeTime){GameObject bullet =(GameObject)Instantiate(bulletPrefab,transform.position +transform.right,Quaternion.identity);var bullet2D =bullet.GetComponent&Rigidbody2D&();bullet2D.velocity = transform.right *bulletSDestroy(bullet, lifeTime);NetworkServer.Spawn(bullet);}void Update(){if (!isLocalPlayer)if (Input.GetKeyDown(KeyCode.Space)){CmdDoFire(3.0f);}}}  注意如果每一帧都发送命令消息,会产生很多的网络流量。  默认情况下,命令是通过0号通道(默认的可靠传输通道)进行传输的。所以默认情况下,所有的命令都会被可靠地发送到。可以使用命令的&Channel&参数修改这个配置。参数是一个整数,表示通道号。1号通道是默认的不可靠传输通道,如果要用这个通道,把这个参数设置为1,示例如下:[Command(channel=1)]  从Unity5.2开始,可以从拥有客户端授权的非物体发出命令。这些物体必须是使用函数NetworkServer.SpawnWithClientAuthority()派生出来的,或者是使用NetworkIdentity.AssignClientAuthority()授权过的。从物体发送出来的命令会在服务器上运行,而不是在相关物体所在的客户端上。
客户端远程过程调用(ClientRPC Calls)
  客户端远程过程调用从的物体发送到客户端的物体上去。他们可以从任何带有NetworkIdentity并被派生出来的物体上发出。因为拥有授权,所以这个过程不存在安全问题。要把一个函数变成客户端远程过程调用,需要给函数添加[ClientRpc]属性,并且为函数名添加&Rpc&前缀。这个函数将在服务端上被调用时,在客户端上执行。所有的参数都将自动传给客户端。  客户端远程调用必须带有&Rpc&前缀。在阅读代码的时候,这将是个提示 & 这个比较特殊,不像一般那样在本地执行。class Player :NetworkBehaviour{[SyncVar][ClientRpc]void RpcDamage(int amount){Debug.Log("Took damage:" +amount);}public void TakeDamage(int amount){if (!isServer)health -=RpcDamage(amount);}}  当使用伺服器模式运行的时候,客户端远程调用将在本地客户端执行 & 即使他其实和运行在同一个进程。因此本地客户端和远程客户端对客户端远程过程调用的处理是一样的。  如果想将[ClientRpc]用在点击事件的同步操作上,不能直接绑定点击事件函数,而是应该起一个新的Rpc函数,点击事件去绑定这个Rpc函数,Rpc函数里才是对点击事件的操作:
&//点击事件&&& public void ClickDXView()&&& {&&&&&&&&&&& RpcDXView();&&& }
&&& [ClientRpc]&&& public void RpcDXView()&&& {&&&&&&&&readyPN.gameObject.SetActive(false);&&&&&&& startGm();&&&&&&& Camera.main.GetComponent&DOTweenPath&().DOPlay();&&& }
回调函数--
[ServerCallback]:只执行在服务器端,并使一些特殊函数(eg:Update)不报错(若在此函数中改变了带有syncvar的变量,客户端不同步)
          (使用ServerCallback时,将Update中的重要语句摘出来写入Rpc函数中并调用)
[ClientCallback]:只执行在客户端
另:[Server]:只执行在服务器端但是不能标识一些特殊函数(可以在这里调用Rpc类函数)
远程过程的参数
  传递给客户端远程过程调用的参数会被序列化并在网络上传送,这些参数可以是:- 基本数据类型(字节,整数,浮点树,字符串,64位无符号整数等)- 基本数据类型的数组- 包含允许的数据类型的结构体- Unity内建的数学类型(Vector3,Quaternion等)- NetworkIdentity- NetworkInstanceId- NetworkHash128- 带有NetworkIdentity组件的物体  远程过程的参数不可以是物体的子组件,像脚本对象或Transform,他们也不能是其他不能在网络上被序列化的数据类型。
  在使用过程中发现一个问题:带有NetworkIdentity的组件在运行之前不能是隐藏的,否则同步会受影响,在代码Start函数中置为SetActive = false,或者因为网络问题一开始隐藏的物体在后续同步中都没有问题。
阅读(...) 评论()Unity 实现Log实时输出到屏幕或控制台上&二& - [ Unity5学习记录 ] - 看云
本文章由cartzhang编写,转载请注明出处。 所有权利保留。
文章链接:
作者:cartzhang
第一部分博客链接:
Github 地址:
一、你还是想要一个控制台来显示信息?
为什么呢?这样就不会占用Unity本身的GUI的显示,不去调用Unity的渲染,转而该为Windows的渲染了。
是不是很惬意,花费少了,还更灵活了。
二、你都需要些什么?
当然是一个控制台窗口和写到控制台的输入了。
代码是歪果仁写的,但是很好用。
首先,输入的代码:
名字为ConsoleInput.cs
using UnityE
using System.C
using System.Runtime.InteropS
using System.IO;
namespace ConsoleTestWindows
public class ConsoleInput
//public delegate void InputText( string strInput );
public event System.Action&string& OnInputT
public string inputS
public void ClearLine()
//System.Text.Encoding test = Console.InputE
Console.CursorLeft = 0;
Console.Write( new String( ' ', Console.BufferWidth ) );
Console.CursorTop--;
Console.CursorLeft = 0;
public void RedrawInputLine()
if ( inputString.Length == 0 )
if ( Console.CursorLeft & 0 )
ClearLine();
System.Console.ForegroundColor = ConsoleColor.G
System.Console.Write( inputString );
internal void OnBackspace()
if ( inputString.Length & 1 )
inputString = inputString.Substring( 0, inputString.Length - 1 );
RedrawInputLine();
internal void OnEscape()
ClearLine();
inputString = "";
internal void OnEnter()
ClearLine();
System.Console.ForegroundColor = ConsoleColor.G
System.Console.WriteLine( "& " + inputString );
var strtext = inputS
inputString = "";
if ( OnInputText != null )
OnInputText( strtext );
public void Update()
if ( !Console.KeyAvailable )
var key = Console.ReadKey();
if ( key.Key == ConsoleKey.Enter )
OnEnter();
if ( key.Key == ConsoleKey.Backspace )
OnBackspace();
if ( key.Key == ConsoleKey.Escape )
OnEscape();
if ( key.KeyChar != '\u0000' )
inputString += key.KeyC
RedrawInputLine();
然后,你还需要一个控制台窗口
using UnityE
using System.C
using System.Runtime.InteropS
using System.IO;
namespace ConsoleTestWindows
/// &summary&
/// Creates a console window that actually works in Unity
/// You should add a script that redirects output using Console.Write to write to it.
/// &/summary&
public class ConsoleWindow
TextWriter oldO
public void Initialize()
// Attach to any existing consoles we have
// failing that, create a new one.
if ( !AttachConsole( 0x0ffffffff ) )
AllocConsole();
oldOutput = Console.O
IntPtr stdHandle = GetStdHandle( STD_OUTPUT_HANDLE );
Microsoft.Win32.SafeHandles.SafeFileHandle safeFileHandle = new Microsoft.Win32.SafeHandles.SafeFileHandle( stdHandle, true );
FileStream fileStream = new FileStream(safeFileHandle, FileAccess.Write);
System.Text.Encoding encoding = System.Text.Encoding.ASCII;
StreamWriter standardOutput = new StreamWriter( fileStream, encoding );
standardOutput.AutoFlush =
Console.SetOut( standardOutput );
catch ( System.Exception e )
Debug.Log( "Couldn't redirect output: " + e.Message );
public void Shutdown()
Console.SetOut( oldOutput );
FreeConsole();
public void SetTitle( string strName )
SetConsoleTitle( strName );
private const int STD_OUTPUT_HANDLE = -11;
[DllImport( "kernel32.dll", SetLastError = true )]
static extern bool AttachConsole( uint dwProcessId );
[DllImport( "kernel32.dll", SetLastError = true )]
static extern bool AllocConsole();
[DllImport( "kernel32.dll", SetLastError = true )]
static extern bool FreeConsole();
[DllImport( "kernel32.dll", EntryPoint = "GetStdHandle", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall )]
private static extern IntPtr GetStdHandle( int nStdHandle );
[DllImport( "kernel32.dll" )]
static extern bool SetConsoleTitle( string lpConsoleTitle );
三、输入和窗口准备齐全了,问题来了。
当你试图编译代码时候,你会发现居然编译报错,各种找不到。
Console.CursorLeft等大量的方法和变量都找不到。
这是因为Untiy5 默认的目标框架Unity3.5 .net sbu base class Libraries.。在Player Setting中,可设置为.Net 2.0。
这就可以改变了VS下的编译环境了。
但是要是你想要修改编译环境为你想要的其他呢?
四、那么问题来了?怎么修改编译环境的目标框架呢?
你肯定不会是想出这个问题的第一人?所以那就有人来解决问题;
动态的修改你的FrameWork,就可以解答这个问题。
代码:UpgradeVSProject.cs
//#define USE_UPGRADEVS
using UnityE
using System.C
using UnityE
using System.IO;
using System.Text.RegularE
class UpgradeVSProject : AssetPostprocessor
#if USE_UPGRADEVS
private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
string currentDir = Directory.GetCurrentDirectory();
string[] slnFile = Directory.GetFiles(currentDir, "*.sln");
string[] csprojFile = Directory.GetFiles(currentDir, "*.csproj");
bool hasChanged =
if (slnFile != null)
for (int i = 0; i & slnFile.L i++)
if (ReplaceInFile(slnFile[i], "Format Version 10.00", "Format Version 11.00"))
hasChanged =
if (csprojFile != null)
for (int i = 0; i & csprojFile.L i++)
if (ReplaceInFile(csprojFile[i], "ToolsVersion=\"3.5\"", "ToolsVersion=\"4.0\""))
hasChanged =
if (ReplaceInFile(csprojFile[i], "&TargetFrameworkVersion&v3.5&/TargetFrameworkVersion&", "&TargetFrameworkVersion&v4.0&/TargetFrameworkVersion&"))
hasChanged =
if (hasChanged)
Debug.LogWarning("Project is now upgraded to Visual Studio 2010 Solution!");
Debug.Log("Project-version has not changed...");
static private bool ReplaceInFile(string filePath, string searchText, string replaceText)
StreamReader reader = new StreamReader(filePath);
string content = reader.ReadToEnd();
reader.Close();
if (content.IndexOf(searchText) != -1)
content = Regex.Replace(content, searchText, replaceText);
StreamWriter writer = new StreamWriter(filePath);
writer.Write(content);
writer.Close();
同样,我写了代码屏蔽的宏定义。使用的时候启用就可以了。
就可以自动升高版本到4.0上,当然你也可以修改代码来升高到其他版本的。
注意:这个代码很明显,需要放置在Editor文件夹下。
五、测试结果
我写了个几行的测试代码:
using UnityE
using System.C
public class Tes : MonoBehaviour {
// Use this for initialization
void Start () {
// Update is called once per frame
void Update ()
if (Input.GetKey(KeyCode.A))
Debug.Log("this is debug log");
System.Console.WriteLine("this is system console write line");
结果就出来了:
别告诉我,这不是你想要的控制台窗口。
你看看,在写Log时,会不会造成你的游戏卡顿了呢??
---------THE END------------------------
若有问题,请随时联系!
非常感谢!!
页面正在加载中

我要回帖

更多关于 unity3d ugui输入框 的文章

 

随机推荐