分类存档: unity3d - 第3页

按power键返回,不出现锁屏,直接进入游戏

android 4.3.x 以上版本,不知道修改了哪里,按power键返回时,会导致游戏分辨率调整。

网上大多数做法是在onConfigurationChanged重新设置游戏的分辨率,这样会在切回来时,游戏可以调整为正确的分辨率。

 

mUnityPlayer.getView().getLayoutParams().width=mUnityPlayer._displayWidth;
mUnityPlayer.getView().getLayoutParams().height=mUnityPlayer._displayHeight;

这种做法基本上算是解决了问题。

实际上更好的方式是按power button后直接返回至游戏。发现unity的debug版本可以实现这个功能,有时间需要反编译下,看看代码差异在哪里。

 

unity 在游戏启动时按home键,再切回游戏黑屏

我们的游戏在启动时,如果切回后台,会几率性出现黑屏及资源加载错误。

我抓了一下android层的异常:

01-20 22:21:48.362: W/IInputConnectionWrapper(6525): showStatusIcon on inactive InputConnection
01-20 22:21:48.440: E/BufferQueue(190): [SurfaceView] connect: BufferQueue has been abandoned!
01-20 22:21:48.440: E/libEGL(6525): EGLNativeWindowType 0x76b53920 already connected to another API
01-20 22:21:48.440: E/libEGL(6525): eglCreateWindowSurface:525 error 3003 (EGL_BAD_ALLOC)
01-20 22:21:48.440: E/Unity(6525): [EGL] Failed to create surface
01-20 22:21:48.440: E/Unity(6525):  
01-20 22:21:48.440: E/Unity(6525): (Filename:  Line: 132)
01-20 22:21:48.440: E/Unity(6525): [EGL] Error:: EGL_BAD_ALLOC: EGL failed to allocate resources for the requested operation.
01-20 22:21:48.440: E/Unity(6525):  
01-20 22:21:48.440: E/Unity(6525): (Filename: ./PlatformDependent/AndroidPlayer/ContextGLES.cpp Line: 132)
01-20 22:21:48.441: E/libEGL(6525): call to OpenGL ES API with no current context (logged once per thread)

在网上搜索了很多文章,没有合适的解决方案。

在测试我们公司另一个项目的游戏时,发现他们没有这个问题,比较我们两个游戏,发现在启动速度上差别很大。

感觉这个问题的出现和启动慢有关系。查看启动部分代码,发现启动的类的field都是直接在类加载时进行的初始化。

感觉这里会阻塞线程,导致的unity初始时间非常长。

写了一个测试用例,分别在Awake(),Start()及类初始化时添加Thread.sleep(15000)的强制延迟。

发现Awake,Start不会阻塞unity的加载,会立即加载出splash image。在类初始化时,消耗大量时间,打出apk包,在手机上运行,也没有阻塞splash image显示。这下可真是奇怪了。

我先把我们游戏中在类加载时初始化的内容全转移至Awake中,再打个包测试下。

经过我们这边和珠海测试团队测试,进游戏时丢贴图的问题没有再次复现。是个好消息。

只剩下最后一个黑屏的问题,这个黑屏并不是BUG,只是客户端代码流程没有处理好。

——————————————————————————————

2015.01.22 更新:

本来以为黑屏是游戏中故意设置的黑屏,把游戏中的黑屏改为绿屏,结果发现黑屏问题依旧。

试着抓了一下异常:

01-22 13:36:59.538: E/XSJData(5438): serverId is null
01-22 13:36:59.675: E/XSJData(5438): serverId is null
01-22 13:38:07.740: E/linker(9195): load_library(linker.cpp:760): library "libmaliinstr.so" not found
01-22 13:38:07.744: E/(9195): appName=com.xsj.moon, acAppName=com.android.cts.openglperf
01-22 13:38:07.744: E/(9195): 0
01-22 13:38:07.744: E/(9195): appName=com.xsj.moon, acAppName=com.android.browser
01-22 13:38:07.744: E/(9195): 0
01-22 13:38:13.985: E/linker(9195): load_library(linker.cpp:760): library "/data/app/com.xsj.moon-1.apk/assets/bin/Data/Managed/mscorlib.dll.so" not found
01-22 13:38:14.501: E/(9195): appName=com.xsj.moon, acAppName=com.android.cts.openglperf
01-22 13:38:14.501: E/(9195): 0
01-22 13:38:14.501: E/(9195): appName=com.xsj.moon, acAppName=com.android.browser
01-22 13:38:14.501: E/(9195): 0
01-22 13:38:14.714: E/linker(9195): load_library(linker.cpp:760): library "/data/app/com.xsj.moon-1.apk/assets/bin/Data/Managed/UnityEngine.dll.so" not found
01-22 13:38:14.800: E/linker(9195): load_library(linker.cpp:760): library "/data/app/com.xsj.moon-1.apk/assets/bin/Data/Managed/Assembly-CSharp-firstpass.dll.so" not found
01-22 13:38:14.902: E/linker(9195): load_library(linker.cpp:760): library "/data/app/com.xsj.moon-1.apk/assets/bin/Data/Managed/Assembly-CSharp.dll.so" not found
01-22 13:38:14.906: E/linker(9195): load_library(linker.cpp:760): library "/data/app/com.xsj.moon-1.apk/assets/bin/Data/Managed/Assembly-UnityScript.dll.so" not found
01-22 13:38:14.909: E/linker(9195): load_library(linker.cpp:760): library "/data/app/com.xsj.moon-1.apk/assets/bin/Data/Managed/HOTween.dll.so" not found
01-22 13:38:14.913: E/linker(9195): load_library(linker.cpp:760): library "/data/app/com.xsj.moon-1.apk/assets/bin/Data/Managed/JsonFx.Json.dll.so" not found
01-22 13:38:14.916: E/linker(9195): load_library(linker.cpp:760): library "/data/app/com.xsj.moon-1.apk/assets/bin/Data/Managed/P31RestKit.dll.so" not found
01-22 13:38:14.918: E/linker(9195): load_library(linker.cpp:760): library "/data/app/com.xsj.moon-1.apk/assets/bin/Data/Managed/Vectrosity.dll.so" not found
01-22 13:38:14.919: E/linker(9195): load_library(linker.cpp:760): library "/data/app/com.xsj.moon-1.apk/assets/bin/Data/Managed/UMGameAnalyticsLibForAndroid.dll.so" not found
01-22 13:38:14.920: E/linker(9195): load_library(linker.cpp:760): library "/data/app/com.xsj.moon-1.apk/assets/bin/Data/Managed/UMGameAnalyticsLibForiOS.dll.so" not found
01-22 13:38:17.802: E/linker(9195): load_library(linker.cpp:760): library "/data/app/com.xsj.moon-1.apk/assets/bin/Data/Managed/System.Core.dll.so" not found
01-22 13:38:17.872: E/linker(9195): load_library(linker.cpp:760): library "/data/app/com.xsj.moon-1.apk/assets/bin/Data/Managed/System.dll.so" not found
01-22 13:38:18.303: E/linker(9195): load_library(linker.cpp:760): library "/data/app/com.xsj.moon-1.apk/assets/bin/Data/Managed/System.Xml.dll.so" not found
01-22 13:38:19.756: E/lsy(9195): UnityAwake
01-22 13:38:20.957: E/linker(9195): load_library(linker.cpp:760): library "/data/app/com.xsj.moon-1.apk/assets/bin/Data/Managed/System.dll.so" not found
01-22 13:38:24.040: E/linker(9195): load_library(linker.cpp:760): library "fmod" not found
01-22 13:38:24.048: E/linker(9195): load_library(linker.cpp:760): library "fmodstudio" not found
01-22 13:38:24.062: E/linker(9195): load_library(linker.cpp:760): library "fmodstudio" not found
01-22 13:38:26.182: E/linker(9195): load_library(linker.cpp:760): library "fmodstudio" not found
01-22 13:38:26.252: E/linker(9195): load_library(linker.cpp:760): library "fmodstudio" not found
01-22 13:38:26.255: E/linker(9195): load_library(linker.cpp:760): library "fmod" not found
01-22 13:38:26.738: E/XSJData(9195): serverId is null
01-22 13:38:26.868: E/XSJData(9195): serverId is null
01-22 13:38:28.460: E/WhetstoneSDK-JNI(9195): on Load native Whetstone

看起来还是程序中有BUG,并不是简单的逻辑异常。

unity中包中只存在对应的dll不存在对应的dll.so,这里应该是unity内部的加载机制被破坏掉了。

在goolge上搜索下unity加载dll的流程。

抓了一下正常流程的日志,在正常流程中也有上面的输出。看起来不是上面的原因。

—————————————————————————————————————-

2015.01.29

这几天为了这个花屏,黑屏的问题做了不了调查,现在基本上确认了点信息:

重现流程:

1、启动游戏

2、在splash image加载完成前,点home键返回主界面

3、点游戏图标进入游戏,出现黑屏。如果继续,则有可能出现花屏。

已经确认的信息:

1、我们的游戏中很多资源都放在的resources目录下,这会导致游戏加载很比较慢,这里可能会出现egl初始化未完成时,点home键返回界面,然后再点回来时,又创建了一次egl windows,而android中不允许同时存在两个egl windows,所以就会出现黑屏。

一条可能有用的信息:

01-29 15:23:12.572: W/MALI(3730): __egl_mali_post_to_window_surface:936: __egl_mali_post_to_window_surface: posting to window surface failed; couldn’t acquire output buffer (surface=0x7cb3b008)

还有另一条,从这里开始不停报错:

01-29 15:23:12.573: D/Unity(3730): [EGL] SwapBuffer: EGL_BAD_ALLOC: EGL failed to allocate resources for the requested operation.
01-29 15:23:12.933: E/Unity(3730): [EGL] Failed to create surface

参考:

http://stackoverflow.com/questions/15561780/createwindowsurface-failed-egl-bad-match

发现一件很奇怪的事,在小米手机上,如果安装完后直接启动游戏,则在游戏中按home键返回,再点游戏图标进入游戏,每次都会重新调用onCreate。

如果一开始使用游戏icon进入游戏,则不会有这个问题。

可能有用的一条log:

01-29 23:01:38.793: W/ManagedEGLContext(18120): doTerminate failed: EGL count is 2 but managed count is 1

黑屏的原因找到了,是因为4.3.1f1中unity每次pause后,eglcontext需要重建,但我们游戏中重建需要的时间太长,而且在重建完成前就是黑屏,而且这里还有另一个问题,如果在黑屏期再按pause返回,则会导致游戏中一个10秒的黑屏等待,如果你短时间内不停pause,则每一次puase导致的10秒等待会累加起来。

另参考:http://stackoverflow.com/questions/2112768/prevent-onpause-from-trashing-opengl-context

http://pastebin.com/U4x5JjAr

http://gamedev.stackexchange.com/questions/12629/workaround-to-losing-the-opengl-context-when-android-pauses

http://www.anddev.org/android-2d-3d-graphics-opengl-problems-f55/minimizing-opengl-texture-reloads-on-pause-resume-t52932.html

 

https://code.google.com/p/replicaisland/source/browse/trunk/src/com/replica/replicaisland/GLSurfaceView.java

——————————————————————————————————–

2015.02.03 不知道时间过去多长了,黑屏和花屏问题终于定位到了,项目代码中真是各种天坑。

先列下解决方案吧:

<activity
            android:name="com.haifi.abc.MainActivity"
            android:configChanges="locale|mcc|mnc|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale"
            android:label="@string/app_name"
            android:windowSoftInputMode="stateHidden"
            android:screenOrientation="sensorLandscape"
            android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:label="@string/app_name" android:name="UnityPlayerActivityEx" android:screenOrientation="landscape" android:configChanges="locale|mcc|mnc|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale">
            <strong><span style="color: #ff0000;">&lt;meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" /&gt;</span></strong>
        &lt;/activity&gt;

1、使用unity中提供的默认UnityPlayerActivity,是从UnityPlayerNativeActivity继承而来,

http://docs.unity3d.com/Manual/PluginsForAndroid.html

这里有一段对UnityPlayerNativeActivity的描述,说明了unityplayer.ForwardnativeEventsToDalvik的作用,

我们项目中不知道是谁竟然删除了这些代码,unity默认生成的android工程中带着此代码的。

2、自己写一个类继承自UnityPlayerActivity,然后补充以下代码:

	protected void onCreate(Bundle paramBundle) {
		super.onCreate(paramBundle);
		if (Build.VERSION.SDK_INT >= 19) {
			getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(
					new View.OnSystemUiVisibilityChangeListener() {
						public void onSystemUiVisibilityChange(
								int paramAnonymousInt) {
							View localView = UnityPlayerActivityEx.this
									.getWindow().getDecorView();
							if ((paramAnonymousInt & 0x4) == 0) {
								localView.setSystemUiVisibility(5894);
							}
						}
					});
		}
	}

	public void onWindowFocusChanged(boolean paramBoolean) {
		super.onWindowFocusChanged(paramBoolean);
		if ((Build.VERSION.SDK_INT >= 14) && (paramBoolean)) {
			getWindow().setFlags(1024, 1024);
			getWindow().getDecorView().setSystemUiVisibility(6);
		}
		if ((Build.VERSION.SDK_INT >= 19) && (paramBoolean)) {
			getWindow().getDecorView().setSystemUiVisibility(5894);
		}
	}

OK,什么花屏和黑屏全都消失不见了。真是天坑。

另外这里还有进一步优化的余地:可以进一步阻止surfaceview的创建,这样按home键再返回,不会重建egl context。

 

——————————————————————————————————————–

2015.02.13记。这周又在处理这个问题,在MainActivity中添加代码后发现在第一次安装后直接在安装界面启动,按home键返回,再点游戏图标,就会直接黑屏。

这周怒了,把unity源码各个函数都添加日志,在android那一层把所有可能调用的函数都添加日志,意外发现MainActivity的onCreate被调用了两次???,不可理解,从理论上讲,MainActivity的onCreate永远只会被调用一次。

又添加测试代码,在MainActivity中设置一个private static int m=0;在onCreate中设置m++,然后输出m的值,发现果然,从启动界面启动游戏时,每次从home键返回都会调用onCreate,而且m的值一直在增加,说明这个进程并没有被结束。只是MainActivity被重复的创建。

我一开始想到的方法是既然MainActivity中多次创建,那根据m的值,只在第一次创建时,生成unityPlayer,其它的时间不再重新创建unityPlayer,这样可以避免unityPlayer被多次创建,就也自然避免的黑屏的问题。

但是这个方法一开始很好,但在测试中发现了问题,我们开始游戏时,会播放一个mp4视频,如果这时候按home返回,再返回游戏,又是黑屏,该死,这是因为我们的开发人员把播放视频放在了MainActivity中,而返回时,又因为onCreate的原因,又丢失掉了播放视频的view。

总之,走了NNNNNNN多的弯路。

到这里我又重新审视了自己的解决方法和问题根源,这里根源就是因为onCreate被调用了多次导致的,如果能解决这个问题,其它所有问题都是自然而解。

幸好老外早就遇到问题了,只是可惜我一开始没有走到正确的方向,导致花费了太多的时间。

好吧下面是一系列的奇遇:

1、我在google搜索: “android acitivity recreate from home button”

2、它建议我搜索: “android activity oncreate from home button”,好吧,同意它。

3、看到一个搜索结果:http://stackoverflow.com/questions/16981793/android-home-key-issue-at-first-time-calling-oncreate

4、果然是我需要的问题,里面建议去:http://code.google.com/p/android/issues/detail?id=2373

5、https://code.google.com/p/android/issues/detail?id=2373 好吧,果然是宝地,问题根源及解决方案(三种)都在里面。

这里我采用了,这个大师的解决方案。(当然,另外的解决方案也可以尝试)

<a href="https://github.com/cleverua/android_startup_activity" rel="nofollow">https://github.com/cleverua/android_startup_activity</a>

总结:也是自己太不了解android开发了,不然这个bug一看到就可以解决掉了。自己虽然花费很多精力,但中间解决问题的学习也让自己增长了不长见识。

unity3d streaming asset文件加载

如果使用www加载资源的方式:

参考:http://docs.unity3d.com/Manual/StreamingAssets.html

安卓的路径需要 “jar:file://”开头,因为安卓自身是apk压缩格式

ios和win需要添加 “file:///”开头。

 

2014.1.4附:

1、这是现在用的加载方式(加载速度很快)

 WWW www = new WWW(path);
                yield return www;
                if (!string.IsNullOrEmpty(www.error))
                {
                    Debug.LogError("www error:" + www.error);
                }
                if (www.assetBundle.mainAsset != null)
                {
                    AssetBundle bundle = www.assetBundle;
                    ConfigDataCSVScriptableObject obj = bundle.mainAsset as ConfigDataCSVScriptableObject;
                    callback(obj);
                    bundle.Unload(true);
                    www.Dispose();
                }
                else
                {
                    Debug.LogError("can't find assetbundle with url:" + path);
                }

2、这是原来用的加载方式(加载速度很慢,慢上4~5倍)

if (File.Exists(path))
                {
                    byte[] bytes = File.ReadAllBytes(path);
                    AssetBundleCreateRequest request = AssetBundle.CreateFromMemory(bytes);
                    yield return request;
                    while (!request.isDone)
                    {
                        yield return request.isDone;
                    }
                    AssetBundle bundle = request.assetBundle;
                    
                    ConfigDataCSVScriptableObject obj = bundle.mainAsset as ConfigDataCSVScriptableObject;
                    callback(obj);
                    bytes = null;
                    bundle.Unload(true);
                }
                else
                {
                    Debug.LogError("can't find assetbundle with path:" + path);
                }

以我现在的能力,还无法了解为什么第二种为什么会很慢,也可能是中间存在一次内存copy的原因?

2014.01.06 附,查找一下慢的原因。

记录了不同加载方式解析消耗的时间,发现解析消耗的时间相差无已,看起来应该加载入内存消耗的时间不相同。

找到原因了:

AssetBundleCreateRequest request = AssetBundle.CreateFromMemory(bytes);

这一句导致的异常的慢。

WWW是加载时直接转为了assetbundle,少了这一步,所以非常快。

如果将第二种方式修改为使用WWW加载assetbundle,速度提升了近7倍。

 

unity3d 中尽量避免使用foreach

foreach会消耗掉额外的内存,生成gc alloc,为了压榨手机的最后一部分性能,尽量避免使用foreach。

遍历数组直接使用:

for(int m=0;m<array.length;m++){

// array[m] 操作

}

遍历dictinory使用,这种方式不会造成gc

  • var enumerator = dummyDic.GetEnumerator();
  • while (enumerator.MoveNext()) {
  • // loop body goes here
  • }

unity命令和打包。

针对不同的平台(android/ios/pc),unity会对不同平台进行针对性优化。

因此如果要针对不同平台打包,最好针对每个平台将项目目录复制出来一份。这样可以避免unity发现平台转化了,对资源进行重新优化。当然了,如果做的游戏小,这点时间是可以忽略不计的。可惜我们的项目转一次资源就得半小时-.-!!。

vs2013下将文件使用unix结束符保存

There are inconsistent line endings in the ‘Assets/Scripts/ui/Mail/MailPrefab.cs’ script. Some are Mac OS X (UNIX) and some are Windows.
This might lead to incorrect line numbers in stacktraces and compiler errors. Many text editors can fix this using Convert Line Endings menu commands.

原因是因为vs下使用 “CR LF”结尾(Windows平台), unity下默认使用”LF”结尾(Unix平台)。

vs下想改为使用LF结尾,打开需要修改的文件,然后“文件->高级保存选项” 行尾选择“Unix (LF)”保存。

对于我们工程数十个文件来说,这不是很优雅的解决方式,幸好早有先人提供更好的方案。

http://www.grebulon.com/software/stripem.php

这个vs插件,可以将项目中所有文件以 LF 结束符保存。

测试配置数据占用的内存大小

游戏中一直不是很清楚配置数据占用了多少内存,现在是使用json转c#对象,转化使用时间也不清楚。

scriptableobject和json相比也不知道谁的性能更优。

现在使用的是dictionary来存储的数据,和hashtable相比谁更快,不知道。现在使用的key是string,使用int是否更快。

以上都需要测试结果:

1、先测试占用的内存。

打一个空场景。

占用的内存如图:

  • total 44.6
  • unity 13.8
  • mono 0.7
  • gfxdriver 17.0
  • fmod 252
  • profiler 12.2
  • assets 19.7
  • other 9.8
  • builtin resources 243.6
  • not saved 26.7
  • scene memory 8.7

原来的工程场景和资源太多了,打包一次太费时间,这里重新建一个工程

内存占用如图:

  • total 18.6
  • unity 2.7
  • mono 0.5
  • gfxdriver 3.3
  • fmod 310k
  • profiler 12.1
  • assets 1.5
  • other 2.1
  • builtin resources 231.1k
  • not saved 145.6k
  • scene memory 15.5k

log_config配置文件大小1M,json未压缩。使用resource.load导入内存增加:1.1M和原文件基本相同。多次使用Resources.load只会增加一份内存。(在assets中显示为text asset)

感觉消耗的内存由other移至assets中。再测试一次,unity死掉了。再重启测试一次,果真如此,other中asset0的东西没有了,assets中多了一个textasset名为log_config。

TextAsset text=Resources.Load(“log_config”) as TextAsset;
TextAsset text2 = Resources.Load(“log_config”) as TextAsset;

连续两行,内存也没有多少变化,TextAsset可能都是引用。果真只是引用。

神奇了。使用Resources.unload后,TextAsset log_config被释放内存。但是other中没有增加内存!!!

我把json中的字符串放入textbox中,内存消耗变的巨大:

主要是other中的managedHeap.usedSize变为了71M,在simple界面中可以看到mono也同步变为了71M。

测试结果,使用Resources.load 加载后,然后使用unload释放掉对象内存,但是好像该对象还可以继续使用 -.-!!。难道是因为内存区还保留着数据导致的?unloadAssets,如果被引用对象再次被使用,会从被加载的地方重新被加载。所以,一个对象完全不被使用后,再unloadAssets。

在这里,我们的配置文件被转化为了c#对象,所以可以直接unload掉,释放内存。

minijson中有个东西占用了内存,转换申请了6M内存,一直没有被释放。如果再转换一个小json比如“{}”就会将内存释放掉。

使用json进行转换,中间产生了8M内存占用,既使将引用对象设置为null,不调用GC.collection()也不会回收内存。

text asset转为json消耗2秒,json存入dictionary消耗1.5秒。

开始测试scriptableobject。

没有测试protobuf,scriptableobject比未压缩json容量仅为20%,加载时间仅为10%,内存消耗仅为20%。完全可以替代json。

另外,字符串可以考虑7z压缩,这样可以使用更小的内存,仅多消耗一点CPU。

scriptableobject无法定义为泛型类。

 

unity3d 动态给按钮添加事件

UIEventListener.Get(bt1).onClick = click;

bt1 是按钮的gameobject

 

游戏登陆场景掉祯排查

我们游戏中场景经常出现掉祯的现象。

fps会突然从30降至15。

原来一直没有找到原因,最近学习unity,使用profiler看运行时的情况,看到我的手机上,掉祯出现时,cpu usage会突然飙升,同时gpu usage会也同步飙升。

cpu上升显示是camera.render使用率大量增加。

gpu上升定位至是RenderForwardOpaque.Render占用时间大量增加导致的。

 

 

 

 

unity3d 中捕获所有的异常

void Start () {
// System.AppDomain.CurrentDomain.UnhandledException +=new System.UnhandledExceptionEventHandler(  _erroHandler);
//Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
AppDomain.CurrentDomain.UnhandledException += new System.UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
// Application.Run(new Game());
Application.RegisterLogCallback(_erroHandler);
Application.RegisterLogCallbackThreaded(_erroHandler);
}

private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
}

private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
Debug.Log(“Application_threadException”);
}

void _erroHandler(string name,string stack,LogType type)
{
}


Warning: Use of undefined constant XML - assumed 'XML' (this will throw an Error in a future version of PHP) in /opt/wordpress/wp-content/plugins/wp-syntaxhighlighter/wp-syntaxhighlighter.php on line 1048